与实体框架 ASP.net MVC 中多个表的可选关系
Posted
技术标签:
【中文标题】与实体框架 ASP.net MVC 中多个表的可选关系【英文标题】:Optional relationship to more than one table in Entity Framework ASP.net MVC 【发布时间】:2016-02-24 18:49:21 【问题描述】:我正在尝试构建一个 ASP.net MVC 应用程序。我无法与数据注释建立某种关系。
我有 3 张桌子,Overhours
、Accountings
、Vacations
。每个Overhour
记录可以有1 个Accounting
或Vacation
记录,但它是可选的。所以,它不需要有一个。这是我的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
记录(如果有的话)时,我希望同时删除Vacation
和Accounting
记录。当我这样使用它时,级联删除被禁用。
我试过这个:
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 约束
我很困惑,我做错了什么?
谢谢
【问题讨论】:
【参考方案1】:DELETE CASCADE 不能这样工作。如果您删除Overhour
,则不会也不应该删除任何其他内容。它以相反的方向工作。如果Accounting
是必需的依赖项,并且您删除了附加到Overhour
的Accounting
实例,那么Overhour
也应该被删除。如果外键可以为空,则不会发生这种情况,因为它将被设置为 DELETE SET NULL。不过,无论哪种方式,删除 Overhour
都不会对 Accounting
或 Vacation
实例产生任何影响。
更新
在这种情况下,您似乎需要创建一对一,因为关系的一侧是可选的,因此相对容易。您只需要:
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
有一个Accounting
,Accounting
有很多Overhour
。这就是为什么它不会在这种情况下删除Accounting
,因为它可能在这个Overhour
实例之外仍然具有有效用途。如果您真的希望 Accounting
绑定到特定的 Overhour
实例,那么您的关系应该是一对一的。
我迷路了,我想我需要阅读更多关于 Fluent Api 的内容。
感谢您的更新。问题是,会计也不需要有加班记录。所以,我猜双方都是可选的。也许这就是它不起作用的原因。大概没有这样的关系类型吧?
你可以有一个一对一的双方都是可选的。但是,两者都需要的相同警告适用:您必须使用流利的配置来提示 EF 哪个是依赖的,哪个是主体。也就是说,我不确定为什么您会期望在任一方向都有删除级联。如果Accounting
不依赖于特定的Overhour
,那么它在逻辑上不应该仅仅因为Overhour
被删除而被删除。如果它在与Overhour
的关系之外没有价值,则应该需要Overhour
。以上是关于与实体框架 ASP.net MVC 中多个表的可选关系的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Asp.net MVC 和实体框架中分页时应用过滤器?
asp.net mvc框架中 怎样在一个 View 内传递多个 Model,最好有代码,谢谢