【问题标题】:Simple cascade delete self referencing table with LINQ to SQL使用 LINQ to SQL 的简单级联删除自引用表
【发布时间】:2013-09-05 21:22:19
【问题描述】:

DELETE 语句与 SAME TABLE REFERENCE 约束冲突 “FK_AuthCategories_Parent”。数据库“MyDB”中发生冲突, 表“dbo.AuthCategories”, “父 ID”列。

如果我尝试删除具有 ParentID 的自引用 FK 的表中的所有内容,我会收到上面的错误,即我需要首先删除子项(即,它尝试删除具有子项的父项,这会破坏FK)。

var dc = from c in db.AuthCategories
         select c;
db.AuthCategories.DeleteAllOnSubmit(dc);
db.SubmitChanges();

是否有一个简单的 LINQ to SQL 查询可以在处理级联删除时删除表中的所有内容?

  • 不想使用 SQL 服务器端解决方案,例如触发器或 ON DELETE CASCADE
  • 需要使用 LINQ to SQL,而不是 EF
  • 希望它尽可能简单,如果可能的话,单行

这是表结构:

[Table(Name = "AuthCategories")]
public class AuthCategory
{
    [Column(IsPrimaryKey = true, IsDbGenerated = true)]
    public int ID { get; set; }

    [Column]
    public string Name { get; set; }

    [Column]
    private int? ParentID { get; set; }
    private EntityRef<AuthCategory> parent;
    [Association(IsForeignKey = true, ThisKey = "ParentID")]
    public AuthCategory Parent
    {
        get { return parent.Entity; }
        set { parent.Entity = value; }
    }
}

【问题讨论】:

    标签: c# sql sql-server linq


    【解决方案1】:

    好的,咖啡开始了,这行得通:

    在类中添加一个 Children IEnumerable:

    private EntitySet<AuthCategory> children = new EntitySet<AuthCategory>();
    [Association(Storage = "children", OtherKey = "ParentID")]
    public IEnumerable<AuthCategory> AuthCatChildren
    {
        get { return children; }
    }
    public IEnumerable<AuthCategory> Children
    {
        get { return (from x in AuthCatChildren select x).AsEnumerable(); }
    }
    

    现在您可以先通过while 循环删除子项:

    // Loop, Deleting all rows with no children (which would delete childless parents and nested grandchild/children)
    int loop = 1;
    while (loop > 0)
    {
        var dbList = from c in db.AuthCategories.ToList()
                        where c.Children.Count() == 0
                        select c;
        loop = dbList.Count();
        db.AuthCategories.DeleteAllOnSubmit(dbList);
        db.SubmitChanges();
    }
    

    【讨论】:

    • L2S 不支持自引用级联删除 - 出于好奇,您为什么不想使用 ON_DELETE_CASCADE?当表中有一百万行时,删除代码将如何执行?
    • 好吧,你可以使用ON_DELETE_CASCADE,但是这个循环提供了更多的控制/可以扩展为只删除某些父/子,而不是强行删除所有内容。
    • 很公平,虽然我仍然认为你只要超过几百行就会碰壁!
    猜你喜欢
    • 1970-01-01
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 2017-08-11
    相关资源
    最近更新 更多