[英]Foreign key with composite key in EF Core
我有以下課程:
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以傳遞此方案?
要根據需要配置所需的關系並級聯刪除,可以在ProductAttribute
實體配置塊中使用以下內容:
b.HasMany(e => e.Values)
.WithOne()
.IsRequired();
IsRequired
就足夠了,因為按照慣例,級聯刪除是必需的,關閉是可選的關系。 當然,如果你願意,你可以添加.OnDelete(DeleteBehavior.Cascade)
- 這將是多余的,但不會受到傷害。
請注意,應該在一個地方配置關系。 所以在ProductAttribute
或ProductAttributeValue
執行它,但從ProductAttributeValue
兩者中(容易出錯,可能導致意外的沖突或覆蓋配置問題)。
為了完整HasOne
,以下是如何在ProductAttributeValue
配置中配置相同的內容(由於缺少導航屬性,需要顯式提供HasOne
泛型類型參數):
b.HasOne<ProductAttribute>()
.WithMany(e => e.Values)
.IsRequired();
編寫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屬性的表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
。
謝謝。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.