EF:多对多为什么Clear()不会只生成一个SQL调用?

时间:2013-08-26 12:03:27

标签: c# sql sql-server entity-framework many-to-many

拥有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();

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

所以,如果我有这两个记录的AB表= {(1,2),(1,3)},上面的代码产生两个'删除'sql调用(一个用于b = 2&amp;另一个用于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) 

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

2 个答案:

答案 0 :(得分:2)

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的实体。

答案 1 :(得分:0)

为什么不这样做:

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

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