我正在努力解决sql异常问题:
FK contstraint可能导致循环或多个级联路径
我知道SO上有很多与之相关的帖子,例如:https://stackoverflow.com/a/852047/1778169和https://stackoverflow.com/a/17127512/1778169
我已经阅读了几次,但我仍然不明白:
我的理解尝试 - 我做对了吗?
在下面的模型中,ForumThread和ForumPost实体都需要User。
删除用户会像这样级联:User > ForumThread > ForumPost
并且像这样:User > ForumPost
,从而为我提供“多个级联删除路径”。
public class ForumThread
{
public int ID {get;set;}
public int UserID {get;set;}
public User User {get;set;}
public Collection<ForumPost> Posts {get;set;}
}
public class ForumPost
{
public int ID {get;set;}
public int UserID {get;set;}
public User User {get;set;}
public int ForumThreadID {get;set;}
public int ForumThread Thread {get;set;}
}
public class User
{
public int ID {get;set;}
public int UserID {get;set;}
public User User {get;set;}
public Collection<ForumThread> Threads {get;set;}
}
如果我已正确理解这一点,那么我将如何设计模型,以便ForumThread和ForumPost实体都需要用户?
我希望ForumThread上的User属性能够识别和列出特定用户启动的线程。
我猜一个选项是通过识别发布第一篇帖子的用户来选择线程。但对于那些应该非常简单的事情来说,这不是太复杂了吗?
答案 0 :(得分:2)
你的模型很好(除了我不明白为什么User
有一个user
属性和一个Thread
而不是Thread
的集合,但是我假设它只是一个复制粘贴错误)。如果所有关系的商业含义是必需,我会根据需要对它们进行建模。
您遇到的异常不是模型本身的问题,而是将此模型映射到特定的关系数据库(SQL Server?)。数据库引擎而非Entity Framework抛出异常。 EF不关心多个级联删除路径,其他数据库引擎可能会支持它们。但你正在使用的那个显然没有。
因此,这是数据库系统的技术限制,解决问题的最佳方法是禁用与Fluent API的部分或全部关系的级联删除(请参阅问题中的第二个链接)。我不会调整模型(比如将一些关系定义为可选的可空userID?
FK)以使其与特定数据库“兼容”。毕竟,概念模型应该 - 尽可能 - 一个数据库无知的想法。
当然,禁用级联删除会改变您删除具有所有线程的用户的方式,但是没有办法避免它。当您删除用户时,您不能再依赖数据库自动删除所有线程(和帖子)。您必须通过循环调用DbSet<User>.Remove
和DbSet<ForumThread>.Remove
来手动删除用户及其所有线程。
我不确切地知道您的业务需求,但对我来说似乎有点不寻常,当用户被删除时,他的所有线程和这些线程的所有帖子(包括其他用户的帖子)都会被删除。将线索和帖子分配给Anonymous
或Community
等系统用户不是更合适吗?在这种情况下,您甚至不希望在User
关系上进行级联删除。