如何删除与隐藏交集表的多对多关联中的记录?
Posted
技术标签:
【中文标题】如何删除与隐藏交集表的多对多关联中的记录?【英文标题】:How to delete records in a many-to-many association with a hidden intersection table? 【发布时间】:2019-09-24 11:52:30 【问题描述】:我们有两个表,table1 和 table2,在 SQL 中定义,具有多对多关系。
按照惯例,我们通过创建一个包含 table1 和 table2 主键的交集表 table1_table2 来实现这一点。
我们已经创建了从 table1 到 table1_table2 以及从 table2 到 table1_table2 的 1 多个 FK。
然后我们让 EF6 创建一个 EDMX,使用从数据库导入。
模型定义了两个实体,table1s 和 table2s,具有多对多关系。
即有POCO类table1包含一个ICollection table2s,class table2包含一个ICollection table1s。
如何清除连接,以便删除table1的所有实例?
这个:
using (var dbContext = new DbContext())
dbContext.table1s.RemoveRange(dbContext.table1s);
dbContext.SaveChanges();
抛出异常:
System.Data.SqlClient.SqlException: The DELETE statement conflicted with the REFERENCE constraint "FK_table1_table2_table1".
我首先尝试消除这种关系:
using (var dbContext = new DbContext())
foreach (var table1 in dbContext.table1s)
table1.table2s = null;
dbContext.table1s.RemoveRange(dbContext.table1s);
dbContext.SaveChanges();
我得到了同样的例外。
所以我尝试明确删除每个 table2 记录:
using (var dbContext = new DbContext())
foreach (var table1 in dbContext.table1s)
foreach (var table2 in table1.table2.ToList()
table1.table2s.Remove(table2);
dbContext.table1s.RemoveRange(dbContext.table1s);
dbContext.SaveChanges();
这似乎行得通,但太乏味了,我很难相信这是我应该这样做的方式。
想法?
【问题讨论】:
不使用 EF 可以为自己省去很多麻烦 :) 当我们完成当前的重构时,我们将能够逐类将 EF 替换为 Dapper 或 NHibernate。但随着紧急但不重要的任务不断涌入,这将是一个漫长的过程。 它有它的位置,但很多时候你不需要它。当你使用像 dapper 这样的东西时,只要它不是超级复杂的图表,就会更加透明。 【参考方案1】:EF
嗯,这就是使用 EF 的方式。
这并不是太多的代码,如果需要,甚至可以泛化。
如果问题是性能,那么它可能部分由
处理-
disablingautomatic change detection
eagerly加载导航集合
并且可能通过直接操作entry states。
或者你可以去
不是 EF
Get(more or less reliably) table name from its DbSet(或者如果可以接受就硬编码)并用普通 SQL 删除所有有问题的行。
基本上为正确的工作使用正确的工具。
EF 通常是修改复杂对象图的不错选择,但另一方面,对于批量记录操作而言,它基本上太重了。
【讨论】:
以上是关于如何删除与隐藏交集表的多对多关联中的记录?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 SqlAlchemy 中的多对多集合中删除所有项目?