实体有两个属性,它们在一对多关系中引用相同的实体类型

时间:2011-11-17 16:57:09

标签: c# entity-framework entity-framework-4.1

这似乎是最常见的关系,但由于某种原因,我无法获得代码优先的EF工作。当我运行下面的代码时,我收到以下错误:

* {“在表'记录'上引入FOREIGN KEY约束'Recording_RecordingLocation'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。\ r \ n不能创建约束。请参阅先前的错误。“} *

我研究过SO和其他地方,但一直无法解决这个问题。我必须有轻微的中风,所以如果这是重复的我道歉。我不认为这是因为我发现的所有其他参考问题都是针对多对多的关系......多对一。

我的情景非常简单......

我有一个实体(Recording),它有两个必需属性RecordingLocation和EditingLocation,它们都是相同类型的WorkLocation。每个录制只有一个RecordingLocation和一个EditingLocation (不是多对多)。我也有必要的导航属性。

每个WorkLocation都是独立的,并且与记录本质上没有关联 - 它只是一个物理位置,在那里进行了一些记录。因此,当我删除录制内容时,我不想删除关联的WorkLocations。

public class Recording
{
    [Key]
    public virtual int Id { get; set; }

    //... other properties not shown here

    public virtual int RecordingLocationId { get; set; }
    public virtual WorkLocation RecordingLocation { get; set; }

    public virtual int EditingLocationId { get; set; }
    public virtual WorkLocation EditingLocation { get; set; }
{


public class WorkLocation
{
    [Key]
    public virtual int Id { get; set; }
    public virtual WorkLocationType Type { get; set; }
    public virtual string Description { get; set; }
    public virtual LogicalStatus Status { get; set; }
}

// I'll use this on the front-end to filter a selection list
// but don't necessarily assume a Work Location is bound to only items of this type
public enum WorkLocationType
{
    RecordingLocation,
    EditingLocation,
    MasteringLocation
}

我错过了什么让这个工作?

1 个答案:

答案 0 :(得分:1)

您的导航属性RecordingLocationEditingLocation是必需的,因为相应的外键属性不可为空。按照惯例,EF假定级联删除对于所需的一对多关系是活动的,如果您有多个此类关系引用同一个表,则会导致问题 - 因此异常。

您必须禁用级联删除(您的业务逻辑似乎也需要它),这只能在Fluent API中使用:

public class MyContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Recording>()
            .HasRequired(r => r.RecordingLocation)
            .WithMany()
            .HasForeignKey(f => f.RecordingLocationId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Recording>()
            .HasRequired(r => r.EditingLocation)
            .WithMany()
            .HasForeignKey(f => f.EditingLocationId)
            .WillCascadeOnDelete(false);
    }
}