我有以下课程
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int ParentId { get; set; }
}
public class Transaction
{
public int Id { get; set; }
public DateTime Date { get; set; }
public string Payee { get; set; }
public string Memo { get; set; }
public Category Category { get; set; }
public Category SubCategory { get; set; }
}
创建的数据库已正确创建 SQL Server Table Columns
问题在于,在SaveChanges上,EF设置了类别属性数据,但没有设置SubCategory。我查看了明确设置外键的操作,但没有成功。
谢谢。
答案 0 :(得分:0)
当您对相关实体有一个引用时,EF通常可以通过约定计算或分配FK名称。它基于类型名称而不是属性名称来执行此操作。当您想要两个引用相同的相关实体类型时,需要显式映射要使用的FK。由于您不是在实体内部声明FK属性(这是很好的IMO),因此您需要对其进行映射(EF6)或为其声明阴影属性(EF Core)
例如,假设您的交易记录表将在类别的modelBuilder
事件中使用OnModelCreating
,具有CategoryId和SubCategoryId列:
[EF6]
modelBuilder.Entity<Transaction>
.HasRequired(x => x.Category)
.WithMany()
.Map(x => x.MapKey("CategoryId"));
modelBuilder.Entity<Transaction>
.HasRequired(x => x.SubCategory)
.WithMany()
.Map(x => x.MapKey("SubCategoryId"));
如果类别和/或子类别是可选的,请将HasRequired
替换为HasOptional
。
[EF核心]
modelBuilder.Entity<Transaction>
.HasOne(x => x.Category)
.WithMany()
.IsRequired()
.HasForeignKey("CategoryId");
modelBuilder.Entity<Transaction>
.HasOne(x => x.SubCategory)
.WithMany()
.IsRequired()
.HasForeignKey("SubCategoryId");
如果可选,请删除.IsRequired()
。
ModelBuilder可能很笨重,因此除了最简单的架构外,我使用实体类型配置声明来显式配置架构,而不是依赖于约定或modelBuilder。