2015-01-26 52 views
2

我對實體框架比較陌生。最近我遇到了這種奇怪的行爲(在我的腦海裏),真讓我感到困惑。將實體的狀態設置爲Deleted從dbContext中刪除實體

爲什麼被跟蹤的實體從dbContext中被移除,如果我將它的狀態設置爲Deleted?

例如:

var customers = db.Customers 
.Where(customer => customer.FirstName.Contains("John")) 
.Take(10) 
.ToList(); 

//Let's iterate through the customers -list 
//and remove the 5th customer 
int i = 1; 
foreach(var customer in customers) 
{ 
    if(i == 5) 
    { 
     //An exception will be thrown 
     db.Entry(customer).State = EntityState.Deleted; 
    } 
    i++; 
} 

當第五客戶的狀態從Unchanged變更爲Deleted整個對象會從上下文,甚至從customers -list被破壞。更糟糕的是:這也會拋出一個異常,因爲這個動作改變了我們正在迭代的列表!

任何人都可以向我解釋爲什麼發生這種情況之前更改已被保存到數據庫通過調用db.SaveChanges()

+0

因爲將實體標記爲已刪除並將其作爲查詢結果返回會很奇怪。 – Shoe 2015-01-26 18:51:13

+0

請包括正在拋出的異常的詳細信息 – 2015-01-26 19:04:43

回答

2

爲什麼被跟蹤的實體從dbContext中被移除,如果我將它的狀態設置爲Deleted?

爲了防止一些真正怪異像這樣...

foreach(var customer in customers) 
{ 
    db.Entry(customer).State = EntityState.Deleted; 
} 

foreach(var customer in customers) 
{ 
    Console.WriteLine("I'm a deleted customer that still exists"); 
} 

餘波從此將迫使我們這樣寫代碼。

foreach(var customer in customers) 
{ 
    //Extra code to make sure nothing deleted is in here 
    if(db.Entry(customer).State != EntityState.Deleted) 
    { 
     //Do work 
    } 
} 

注意對象仍然存在於ObjectStateManager但與對象圖中的任何正常交互不會產生任何刪除的對象。你仍然可以看到它像這樣存在...

var customer = customers.First(); 
db.Entry(customer).State = EntityState.Deleted; 
Console.WriteLine(db.Entry(customer).State.ToString()); //Deleted 
+0

謝謝您的回答。 我假設當你將一個實體的狀態設置爲Deleted時,將意味着「標記爲刪除」而不是「現在實際上已被刪除」。 PS: – user3118216 2015-01-26 19:37:59

+1

實體框架在技術上仍然「標記爲刪除」;因此該項目仍在ObjectStateManger中。但是,dbContext足夠聰明,可以假設它「被標記爲刪除」,你實際上並不想與對象進行交互。 'SaveChanges()'實際上會執行命令從存儲和ObjectStateManager中刪除項目。 – Claies 2015-01-26 19:48:28