【问题标题】:Optional relationship to more than one table in Entity Framework ASP.net MVC与实体框架 ASP.net MVC 中多个表的可选关系
【发布时间】:2016-02-24 18:49:21
【问题描述】:

我正在尝试构建一个 ASP.net MVC 应用程序。我无法与数据注释建立某种关系。

我有 3 张桌子,OverhoursAccountingsVacations。每个Overhour 记录可以有1 个AccountingVacation 记录,但它是可选的。所以,它不需要有一个。这是我的Overhour 模型:

public class Overhour
{

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int OverhourId { get; set; }

    ....

    public int? AccountingId { get; set; }
    public virtual Accounting Accounting { get; set; }

    public int? VacationId { get; set; }
    public virtual Vacation Vacation { get; set; }
}

当我删除我的Overhour 记录(如果有的话)时,我希望同时删除VacationAccounting 记录。当我这样使用它时,级联删除被禁用。

我试过这个:

public class Overhour
{

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int OverhourId { get; set; }

    ....

    public virtual Accounting Accounting { get; set; }

    public virtual Vacation Vacation { get; set; }
}

级联删除有效,但实体框架会创建诸如“Accounting_AccountingId”之类的字段,这也是必需的。这些不应该是必需的。

我尝试的最后一件事是:

public class Overhour
{

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int OverhourId { get; set; }

    ....

    public int AccountingId { get; set; }
    public virtual Accounting Accounting { get; set; }

    public int VacationId { get; set; }
    public virtual Vacation Vacation { get; set; }
}

但这一次它给了我这样的错误:

在表 xxx 上引入 FOREIGN KEY xxx 约束可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束

我很困惑,我做错了什么?

谢谢

【问题讨论】:

    标签: c# asp.net asp.net-mvc entity-framework orm


    【解决方案1】:

    DELETE CASCADE 不能这样工作。如果您删除Overhour,则不会也不应该删除任何其他内容。它以相反的方向工作。如果Accounting 是必需的依赖项,并且您删除了附加到OverhourAccounting 实例,那么Overhour 也应该被删除。如果外键可以为空,则不会发生这种情况,因为它将被设置为 DELETE SET NULL。不过,无论哪种方式,删除 Overhour 都不会对 AccountingVacation 实例产生任何影响。

    更新

    在这种情况下,您似乎需要创建一对一,因为关系的一侧是可选的,因此相对容易。您只需要:

    public class Overhour
    {
        ...
    
        public int? AccountingId { get; set; } // optional
        public virtual Accounting Accounting { get; set; }
    }
    
    public class Accounting
    {
        ...
    
        public int OverhourId { get; set; } // required
        public virtual Overhour Overhour { get; set; }
    }
    

    这样,删除Overhour 将级联并删除关联的Accounting,因为它依赖于Overhour

    只有当关系的双方都需要时,事情才会变得复杂。然后,您必须使用 fluent 配置将一个设置为主体,一个设置为从属,因为此时 EF 无法自行做出此决定。

    【讨论】:

    • 实际上级联删除在我的第二个示例中有效。我很混乱。那么,在我的情况下我应该怎么做?我应该自己删除相关记录吗?因为我在删除加班记录时需要删除会计和休假记录。
    • 嗯,问题是你如何对待他们。默认情况下,这将创建一对多,即Overhour 有一个AccountingAccounting 有很多Overhour。这就是为什么它不会在这种情况下删除Accounting,因为它可能在这个Overhour 实例之外仍然具有有效用途。如果您真的希望 Accounting 绑定到特定的 Overhour 实例,那么您的关系应该是一对一的。
    • 我迷路了,我想我需要阅读更多关于 Fluent Api 的内容。
    • 感谢您的更新。问题是,会计也不需要有加班记录。所以,我猜双方都是可选的。也许这就是它不起作用的原因。大概没有这样的关系类型吧?
    • 你可以有一个一对一的双方都是可选的。但是,两者都需要的相同警告适用:您必须使用流利的配置来提示 EF 哪个是依赖的,哪个是主体。也就是说,我不确定为什么您会期望在任一方向都有删除级联。如果Accounting 不依赖于特定的Overhour,那么它在逻辑上不应该仅仅因为Overhour 被删除而被删除。如果它在与Overhour 的关系之外没有价值,则应该需要Overhour
    猜你喜欢
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    • 1970-01-01
    相关资源
    最近更新 更多