我是否理解正确? FK约束可能导致循环或多个级联路径'

时间:2014-03-09 12:02:13

标签: asp.net-mvc entity-framework foreign-keys

我正在努力解决sql异常问题:

  

FK contstraint可能导致循环或多个级联路径

我知道SO上有很多与之相关的帖子,例如:https://stackoverflow.com/a/852047/1778169https://stackoverflow.com/a/17127512/1778169

我已经阅读了几次,但我仍然不明白:

  1. 此错误的确切含义,
  2. 如何设计模型以避免它
  3. 我的理解尝试 - 我做对了吗?

    在下面的模型中,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属性能够识别和列出特定用户启动的线程。

    我猜一个选项是通过识别发布第一篇帖子的用户来选择线程。但对于那些应该非常简单的事情来说,这不是太复杂了吗?

1 个答案:

答案 0 :(得分:2)

你的模型很好(除了我不明白为什么User有一个user属性和一个Thread而不是Thread的集合,但是我假设它只是一个复制粘贴错误)。如果所有关系的商业含义是必需,我会根据需要对它们进行建模。

您遇到的异常不是模型本身的问题,而是将此模型映射到特定的关系数据库(SQL Server?)。数据库引擎而非Entity Framework抛出异常。 EF不关心多个级联删除路径,其他数据库引擎可能会支持它们。但你正在使用的那个显然没有。

因此,这是数据库系统的技术限制,解决问题的最佳方法是禁用与Fluent API的部分或全部关系的级联删除(请参阅问题中的第二个链接)。我不会调整模型(比如将一些关系定义为可选的可空userID? FK)以使其与特定数据库“兼容”。毕竟,概念模型应该 - 尽可能 - 一个数据库无知的想法。

当然,禁用级联删除会改变您删除具有所有线程的用户的方式,但是没有办法避免它。当您删除用户时,您不能再依赖数据库自动删除所有线程(和帖子)。您必须通过循环调用DbSet<User>.RemoveDbSet<ForumThread>.Remove来手动删除用户及其所有线程。

我不确切地知道您的业务需求,但对我来说似乎有点不寻常,当用户被删除时,他的所有线程和这些线程的所有帖子(包括其他用户的帖子)都会被删除。将线索和帖子分配给AnonymousCommunity等系统用户不是更合适吗?在这种情况下,您甚至不希望在User关系上进行级联删除。