如何在SQLite和Entity Framework 6中使用ON DELETE CASCADE

时间:2017-11-29 14:10:19

标签: c# .net sqlite entity-framework-6

我无法使用SQLite和Entity Framework 6(EF6)使用 ON DELETE CASCADE 。有什么我想念的吗?

我使用Visual Studio 2015在C#中创建了一个Windows窗体应用程序.EF6和SQLite在我的应用程序中很好地协同工作,我可以插入和检索数据。但是当谈到删除东西时,删除一行/实体工作正常,但级联根本不起作用。 使用 DBite for SQLite ,我删除了完全相同的行,并且级联工作。

这是我的表,代表节点:

CREATE TABLE `Nodes` (
    `NodeId`    INTEGER,
    `ParentId`  INTEGER,
    `Label` TEXT,
    PRIMARY KEY(`NodeId`),
    FOREIGN KEY(`ParentId`) REFERENCES `Nodes`(`NodeId`) ON DELETE CASCADE
);

这就是我删除“root”节点的方式(假设用cascade删除每个子节点):

var noParentItems = entities.Nodes.Where(n => n.ParentId == null);
foreach (var root in noParentItems)
{
     //entities.Entry(root).State = EntityState.Deleted;
     entities.Nodes.Remove(root);
}
entities.SaveChanges();

注意: 我也尝试了注释版本删除“root”。 在这里,您看到我正在循环捕获每个根节点,但这并不重要。

我正在使用EF6的数据库优先方法。请注意,我不想修改任何生成的文件来解决此问题。

此外,这些解决方案对我不起作用:

请随时询问您可能需要的任何其他信息。

感谢。

2 个答案:

答案 0 :(得分:0)

您在查询中没有使用AsNoTracking,我知道,但即便如此,您也可以尝试这样做;

foreach (var root in noParentItems)
{
     entities.Nodes.Attach(root);
     entities.Entry(root).State = EntityState.Deleted;
}

或者像这样;

foreach (var root in noParentItems)
{
     var newRoot = new Node{ NodeId = root.NodeId };
     entities.Nodes.Attach(newRoot);
     entities.Entry(newRoot).State = EntityState.Deleted;
}

答案 1 :(得分:0)

感谢评论,我发现了如何解决这个问题。

首先我看了这个答案: Cascade on delete not cascading with EF

重要的是这句话:

  

实体框架实际上是一个ADO.NET数据提供者   本身包装一个ADO.NET数据提供程序(SQLite,具体而言)。   通常,实体框架将打开数据库连接   只要它需要一个;这些自动打开的连接是   实体框架完成后自动关闭。   由于其ADO.NET,此默认行为适用于SQL Server   提供者的连接池。但是,它并不适用   SQLite,由于SQLite连接上存在各种“属性”   本身。一个例子是“PRAGMA foreign_keys = ON”,它强制执行   仅用于该SQLite数据库连接的外键。如果是实体   框架随意打开和关闭其连接,然后是SQLite   像这样的PRAGMA就丢失了。

因此,如果有放置指令的地方,那么它只会出现在连接字符串中。

因此我补充说:

0.10000000149011612

现在它运作正常!