使用Entity Framework代码优先定义外键约束

时间:2012-11-03 19:17:06

标签: entity-framework

我有一个名为Code的实体类。它存储了不同种类的类别 - 我需要创建许多小型表所需的数据,例如用户类别,费用类别,地址类型,用户类型,文件格式等。

public class Code
{
    public int Id { get; set; }
    public string CodeType { get; set; }
    public string CodeDescription { get; set; }


    public virtual ICollection<Expense> Expenses { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
                   :
                   : // many more

}

班级Expense如下所示:

public class Expense
{
    public int Id { get; set; }

    public int CategoryId { get; set; }
    public virtual Code Category { get; set; }

    public int SourceId { get; set; }

    public double Amount { get; set; }
    public DateTime ExpenseDate { get; set; }
}

通过上述类定义,我使用Code映射在ExpenseCategoryId之间建立了1:多个关系。

我的问题是,我想将SourceId中的Expense字段映射到Code对象。这意味着,Expense对象将包含

public Code Source { get; set; }

如果我使用它,在运行时我会收到有关循环依赖的错误。

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

您需要在两个关系中的至少一个(或两者)上禁用级联删除。 EF为两个关系按约定启用级联删除,因为两者都是 required ,因为外键属性不可为空。但SQL Server不接受由两个关系引入的同一个表上的多个级联删除路径。这就是你例外的原因。

您必须使用Fluent API覆盖约定:

public class Code
{
    public int Id { get; set; }
    //...
    public virtual ICollection<Expense> Expenses { get; set; }
    //...
}

public class Expense
{
    public int Id { get; set; }

    public int CategoryId { get; set; }
    public virtual Code Category { get; set; }

    public int SourceId { get; set; }
    public virtual Code Source { get; set; }
    //...
}

使用Fluent API进行映射;

modelBuilder.Entity<Expense>()
    .HasRequired(e => e.Category)
    .WithMany(c => c.Expenses)
    .HasForeignKey(e => e.CategoryId)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<Expense>()
    .HasRequired(e => e.Source)
    .WithMany()
    .HasForeignKey(e => e.SourceId)
    .WillCascadeOnDelete(false);