我无法使用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的数据库优先方法。请注意,我不想修改任何生成的文件来解决此问题。
此外,这些解决方案对我不起作用:
请随时询问您可能需要的任何其他信息。
感谢。
答案 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
现在它运作正常!