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

Posted

技术标签:

【中文标题】实体有两个属性,它们都在一对多关系中引用相同的实体类型【英文标题】:Entity has two properties which both reference the same entity type in one-to-many relationship 【发布时间】:2011-11-17 16:57:09 【问题描述】:

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

*"在表 'Recordings' 上引入 FOREIGN KEY 约束 'Recording_RecordingLocation' 可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。\r\ n无法创建约束。查看以前的错误。"*

我研究过 SO 和其他地方,但无法弄清楚这一点。我一定是轻微中风,所以如果这是重复的,我道歉。我不认为这是因为我发现的所有其他参考问题都是针对多对多关系的……多对一。

我的场景很简单……

我有一个实体(记录),它有两个必需的属性 RecordingLocation 和 EditingLocation,它们都是同一类型的 WorkLocation。每个 Recording 都有一个 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

让这个工作我缺少什么?

【问题讨论】:

您真的是在标题中写的一对一而不是一对多吗?不能在同一个工作场所进行两个或多个录音吗? 是的,它是一对多的。我有没有在我的问题的某个地方说“一对一”?我在此评论后重读但没有找到它,如果有,请编辑。 :-) @Slauma OMG 我瞎了 谢谢,修好了! 【参考方案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);
    

【讨论】:

是的,这解决了问题。实际上,我之前曾尝试过这样做,但不理解所需的流利语法……尤其是 .WithMany()。我现在明白了,这很有效。非常感谢您的周到回答。

以上是关于实体有两个属性,它们都在一对多关系中引用相同的实体类型的主要内容,如果未能解决你的问题,请参考以下文章

核心数据 - 具有一对多关系的实体正在检索除“关系”实体之外的所有实体对象的属性

两个自我引用的一对多关系

Hibernate一对多关系操作

entity framework 6 添加实体必须用设计器拖吗

NSPredicate:“添加”一对多关系CoreData中所有实体的属性值

JPA:如何具有相同实体类型的一对多关系