我有以下课程:
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。
该项目是外部模块,因此我的流利的API配置是在目标应用程序DbContext OnModelCreating中调用的扩展。我应该配置每个属性,其他引用不起作用。
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来通过这种情况?
答案 0 :(得分:2)
为了根据需要配置所需的关系并进行级联删除,可以在ProductAttribute
实体配置块中使用以下内容:
b.HasMany(e => e.Values)
.WithOne()
.IsRequired();
IsRequired
就足够了,因为按照惯例,级联删除对于必需关系是打开的,对于可选关系是关闭的。当然,您可以根据需要添加.OnDelete(DeleteBehavior.Cascade)
-这将是多余的,但不会受到损害。
请注意,关系应在单个位置配置。不论是在ProductAttribute
还是ProductAttributeValue
中都可以,但绝不能都这样做(容易出错,可能会导致意外的冲突或压倒配置问题)。
为完整起见,您可以在ProductAttributeValue
配置中配置相同的内容(由于缺少导航属性,因此需要显式提供HasOne
泛型类型参数):
b.HasOne<ProductAttribute>()
.WithMany(e => e.Values)
.IsRequired();
答案 1 :(得分:1)
编写您的ProductAttribute
配置,如下所示:
modelBuilder.Entity<ProductAttribute>(b =>
{
b.ToTable("ProductAttributes");
b.HasKey(x => new {x.ProductId, x.AttributeId});
b.HasMany(pa => pa.Values).WithOne().IsRequired();
});
但是存在可读性的问题。这会将列ProductAttributeProductId
和ProductAttributeAttributeId
作为复合外键添加到shadow property的表ProductAttributeValues
中。如果要使表ProductAttributeValues
中的复合外键更具可读性,则可以按以下方式更新模型ProductAttributeValue
模型类:
public class ProductAttributeValue
{
public Guid Id { get; set; }
public Guid ProductId { get; set; }
public Guid AttributeId { get; set; }
public string Name { get; set; }
}
然后按如下所示更新ProductAttribute
配置:
modelBuilder.Entity<ProductAttribute>(b =>
{
b.ToTable("ProductAttributes");
b.HasKey(x => new {x.ProductId, x.AttributeId});
b.HasMany(pa => pa.Values).WithOne().HasForeignKey(pa => new {pa.ProductId, pa.AttributeId});
});
表ProductAttributeValues
中的组合外键现在将分别生成为ProductId
和AttributeId
。
谢谢。