如何在 Code First EF 中为一对多关系使用组合键
How do I use a composite key for a one to many relationship in Code First EF
我正在使用 EF Code First。
我需要两个 tables,LedgerCategories
和 LedgerSubCategories
具有一对多关系(类别 -> 子类别),每个中的键都是代码(字符串) - 即分别为 LedgerCategoryCode
和 LedgerSubCategoryCode
。但是,我需要允许不同类别的 SubCategoryCode 值相同。
例如类别代码 = REHAB,子类别代码 = MATL、CONTR 和 FEES;和 CategoryCode = MAINT、SubCategoryCodes = MATL、CONTR 和 FEES。
我想我需要使用复合键并在 LedgerSubCategories table 中包含 CategoryCode 和 SubCategoryCode 字段。目前我有:
public class LedgerCategory
{
[Key]
public string LedgerCategoryCode { get; set; }
public string Description { get; set; }
public List<LedgerSubCategory> LedgerSubCategories { get; set; }
}
public class LedgerSubCategory
{
[Key, Column(Order = 0)]
public string LedgerCategoryCode { get; set; }
[Key, Column(Order = 1)]
public string LedgerSubCategoryCode { get; set; }
public string Description { get; set; }
}
我仅使用 LedgerCategory
class 的实例为这些 table 播种,每个实例都包含适当实例化的 LedgerSubCategory
classes 的列表.这似乎既可以正确设置数据库模式(在我看来),也可以适当地填充两个 table。
但是,当我重新实例化 LedgerCategory
的简单列表时,即
using (var db = new BusinessLedgerDBContext())
{
var LedgerCategories = db.LedgerCategories.ToList();
}
LedgerCategory
个实例不包含它们各自的关联 LedgerSubCategory
个实例列表。
我试图避免在 LedgerSubCategories
中引入一个唯一的数字或 Guid ID 字段作为 PK 并仅索引其他代码字段,这看起来像是一种混乱。我没有尝试过这个,但我不确定它会导致重新实例化 LedgerCategories
和关联 LedgerSubCategories
.
的任何不同结果
任何关于如何正确执行此操作并获得正确结果的建议都将受到赞赏。
我想,为了回答我自己的问题,我发现在 Code First 框架建立时,用 Fluent API 覆盖相应 DbContext 中的 OnModelCreating() 以建立一对多关系和外键所需的数据库模式。似乎没有其他方法可以做到这一点,例如使用属性。根据其他人的许多说法,包括 MSDN,Fluent API 似乎是所需要的。但是,这导致我遇到一个新问题或一系列问题,我已将其作为问题提出 。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Configures the one-many relationship between Categories and
// SubCategories, and established the Foreign Key in SubCategories
modelBuilder.Entity<Category>()
.HasMany<SubCategory>(c => c.SubCategories)
.WithRequired(s => s.Category)
.HasForeignKey<string>(s => s.CategoryCode);
}
我正在使用 EF Code First。
我需要两个 tables,LedgerCategories
和 LedgerSubCategories
具有一对多关系(类别 -> 子类别),每个中的键都是代码(字符串) - 即分别为 LedgerCategoryCode
和 LedgerSubCategoryCode
。但是,我需要允许不同类别的 SubCategoryCode 值相同。
例如类别代码 = REHAB,子类别代码 = MATL、CONTR 和 FEES;和 CategoryCode = MAINT、SubCategoryCodes = MATL、CONTR 和 FEES。
我想我需要使用复合键并在 LedgerSubCategories table 中包含 CategoryCode 和 SubCategoryCode 字段。目前我有:
public class LedgerCategory
{
[Key]
public string LedgerCategoryCode { get; set; }
public string Description { get; set; }
public List<LedgerSubCategory> LedgerSubCategories { get; set; }
}
public class LedgerSubCategory
{
[Key, Column(Order = 0)]
public string LedgerCategoryCode { get; set; }
[Key, Column(Order = 1)]
public string LedgerSubCategoryCode { get; set; }
public string Description { get; set; }
}
我仅使用 LedgerCategory
class 的实例为这些 table 播种,每个实例都包含适当实例化的 LedgerSubCategory
classes 的列表.这似乎既可以正确设置数据库模式(在我看来),也可以适当地填充两个 table。
但是,当我重新实例化 LedgerCategory
的简单列表时,即
using (var db = new BusinessLedgerDBContext())
{
var LedgerCategories = db.LedgerCategories.ToList();
}
LedgerCategory
个实例不包含它们各自的关联 LedgerSubCategory
个实例列表。
我试图避免在 LedgerSubCategories
中引入一个唯一的数字或 Guid ID 字段作为 PK 并仅索引其他代码字段,这看起来像是一种混乱。我没有尝试过这个,但我不确定它会导致重新实例化 LedgerCategories
和关联 LedgerSubCategories
.
任何关于如何正确执行此操作并获得正确结果的建议都将受到赞赏。
我想,为了回答我自己的问题,我发现在 Code First 框架建立时,用 Fluent API 覆盖相应 DbContext 中的 OnModelCreating() 以建立一对多关系和外键所需的数据库模式。似乎没有其他方法可以做到这一点,例如使用属性。根据其他人的许多说法,包括 MSDN,Fluent API 似乎是所需要的。但是,这导致我遇到一个新问题或一系列问题,我已将其作为问题提出
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Configures the one-many relationship between Categories and
// SubCategories, and established the Foreign Key in SubCategories
modelBuilder.Entity<Category>()
.HasMany<SubCategory>(c => c.SubCategories)
.WithRequired(s => s.Category)
.HasForeignKey<string>(s => s.CategoryCode);
}