问题描述
我有以下类:
public class ProductAttribute
{
public Guid ProductId { get; set; }
public Guid AttributeId { get; set; }
public List<ProductAttributeValue> Values { get; set; }
public object[] GetKeys()
{
return new object[] {ProductId, AttributeId};
}
}
public class Product
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public class Attribute
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public class ProductAttributeValue
{
public Guid Id { get; set; }
public string Name { get; set; }
}
在原始情况下,Product和Attribute是AggregateRoot,所以我想跳过属性参考。值是一个简单的实体,但是您需要在我的ProductAttribute类中将其作为列表引用,因为您看到该类具有复合键。但是我想要在ProductAttribute
和ProductAttributeValue之间与级联删除建立必要的关系。
In origin case Product and Attribute are AggregateRoot so I want skip navigate that by property references. Value is a simple entity but I need that as list reference in my ProductAttribute class as you see that class have composite key. But I want a required relationship with cascade delete between ProductAttribute and ProductAttributeValue.
该项目是外部模块,所以我流畅的API配置是扩展,在目标应用程序DbContext OnModelCreating中调用。我应该配置每个属性,否则其他引用将不起作用。
This project is external module, so my fluent API configurations are extension which called in target app DbContext OnModelCreating. I should config every properties and references else didn't work.
builder.Entity<ProductAttribute>(b =>
{
b.ToTable("ProductAttributes");
b.HasKey(x => new {x.ProductId, x.AttributeId});
//I should config ProductAttributeValue one-to-many manually here
}
builder.Entity<Product>(b =>
{
b.ToTable("Products");
b.HasKey(x => x.Id);
}
builder.Entity<Attribute>(b =>
{
b.ToTable("Attributes");
b.HasKey(x => x.Id);
}
builder.Entity<ProductAttributeValue>(b =>
{
b.ToTable("ProductAttributeValues");
b.HasKey(x => x.Id);
//I should config ProductAttribute many-to-one manually here
}
如何为ProductAttribute实体配置Fluent API以通过这种情况?
How can you configure your Fluent API for ProductAttribute entity to passing this scenario?
推荐答案
为了根据需要配置所需的关系并进行级联删除,可以在<$ c $中使用以下内容c> ProductAttribute 实体配置块:
In order to configure the desired relationship as required and cascade delete, you can use the following inside the ProductAttribute
entity configuration block:
b.HasMany(e => e.Values)
.WithOne()
.IsRequired();
IsRequired
就足够了,因为按照惯例,级联删除为必需关系打开,为可选关系关闭。当然,如果需要,您可以添加 .OnDelete(DeleteBehavior.Cascade)
-这是多余的,但不会造成伤害。
IsRequired
is enough because by convention cascade delete is on for required and off for optional relationships. Of course you can add .OnDelete(DeleteBehavior.Cascade)
if you want - it will be redundant, but won't hurt.
请注意,应在单个位置配置关系。因此,请在 ProductAttribute
或 ProductAttributeValue
中执行此操作,但不要同时在两者中进行(容易出错,可能会导致意外的冲突或覆盖配置
Please note that the relationships should be configured in a single place. So do it either in ProductAttribute
or ProductAttributeValue
, but never in both (error prone, may cause unexpected conflicting or overriding configuration issues).
为完整起见,这是您可以在 ProductAttributeValue
配置中配置相同内容的方法(要求显式提供 HasOne
泛型类型参数(由于缺少导航属性):
For completeness, here is how you can configure the same inside ProductAttributeValue
configuration (requires explicitly providing the HasOne
generic type argument due to the lack of navigation property):
b.HasOne<ProductAttribute>()
.WithMany(e => e.Values)
.IsRequired();
这篇关于EF Core中带有复合键的外键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!