EF:很多对很多为什么Clear()不只生成一个sql调用

本文关键字:一个 调用 sql 为什么 Clear EF | 更新日期: 2023-09-27 18:29:05

具有2个实体:A *<-->* B多对多关系和相应的3个表:A, B, AB

正在尝试以下代码:

 var tempA = this.dbContext.A.
                  .Where(a => a.UID == 1)
                  .FirstOrDefault();
 // {check for null here}
 tempA.B.Clear();
 this.dbContext.SaveChanges();

似乎为tempA.B集合中的每个b生成了对数据库的多个"Delete"sql调用(有些奇怪,除非我遗漏了什么)。

因此,如果我有一个AB表,其中有这2条记录={(1,2),(1,3)},上面的代码会产生两个"删除"sql调用(一个用于b=2,另一个用于b=3),类似于这样:

 1. DELETE FROM AB WHERE (A_UID = 1) AND (B_UID = 2)
 and 
 2. DELETE FROM AB WHERE (A_UID = 1) AND (B_UID = 3) 

但我想要一些EF代码,它可以产生如下简单的东西?

 DELETE FROM AB WHERE (A_UID = 1) 

EDIT:我不明白EF为什么要解析所有内部引用,并为每个引用生成一个删除,而不是为所有引用生成一次删除。

EF:很多对很多为什么Clear()不只生成一个sql调用

dbContext.Database.ExecuteSqlCommand("DELETE FROM AB WHERE (A_UID = 1)");

是用单个SQL命令实现这一点的唯一方法。EF不会跟踪您是否已加载/附加所有或仅加载部分相关实体。在这种情况下,您可以调用Clear。。。

var tempA = new A { UID = 1, B = new List<B>() }
tempA.B.Add(new B { UID = 2 });
using (var dbContext = new MyContext())
{
    dbContext.A.Attach(tempA);
    tempA.B.Clear();
    dbContext.SaveChanges();
}

在这种情况下,从联接表中删除A.UID=1的所有条目是错误的,因为通过清除集合,您只删除了B.UID=2的实体,而没有删除B.UID=3的实体。

为什么不做一些类似的事情:

var temp = this.dbContext.AB.Where(ab => ab.A.UID == 1 && ab.B.UID == 2);
temp.Clear();

我没有测试它,但也许这会给更好的想法?