2013-08-26 17 views
0

擁有2個實體:A *<-->* B多對多關係和相應的3個表格:A, B, ABEF:多對多爲什麼Clear()不會只生成一個sql調用?

嘗試下面的代碼:

var tempA = this.dbContext.A. 
        .Where(a => a.UID == 1) 
        .FirstOrDefault(); 

// {check for null here} 

tempA.B.Clear(); 

this.dbContext.SaveChanges(); 

似乎產生多個「刪除」 SQL調用數據庫,換每個tempA.B收集b(有些奇怪,除非我想念的東西)。所以,如果我有這些2記錄= {(1,2),(1,3)}的AB表,上面的代碼會產生兩個'Delete'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) 

編輯:我不明白爲什麼EF是解析所有的內部引用,並生成一個刪除,他們每個人,而不是一個刪除所有。

+1

你可以嘗試尋找實體框架擴展進行批量更新/刪除:https://github.com/loresoft/EntityFramework.Extended – Thewads

+0

@Thewads :這看起來不錯;這絕對是要記住的東西; – Learner

回答

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。

+0

好吧,我想現在我明白了Clear()隻影響EF無法預測的附加實體是否全部。 ..太糟糕了,沒有其他簡單的方法來實現我想要的...我可能會去調用存儲過程然後。 – Learner

+0

我注意到,執行一個命令或存儲過程是在一個單獨的事務中完成的,而不是調用SaveContext的那個事務。對此有何想法?謝謝! – Learner

+0

@Cristi:如果你需要在一個事務中將它們包裝到TransactionScope中,如下所示:http://stackoverflow.com/a/7525625/270591 – Slauma

0

爲什麼不這樣做:

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

我沒有測試,但梅比這會給更好的主意的?

+0

AB不是實體,只有A和B是實體,AB只是用於多對多關係的表 – Learner

+0

爲什麼不創建AB實體? –

+0

當使用數據庫優先的方法時,EF自動創建模型...模型是好的 – Learner

相關問題