2011-06-22 61 views
5

我有一個場景,我必須更新實體,如果它存在或添加一個新的,如果它不。實體框架:更新實體或添加,如果它不存在

我想爲此執行一個單一的方法(如果它是單次訪問服務器,那將會很棒)。

在EF中是否有類似的東西?

現在我的代碼如下所示:

var entity = db.Entities.FirstOrDefault(e => e.Id == myId); 
if (entity == null) 
{ 
    entity = db.Entities.CreateObject(); 
    entity.Id = myId; 
} 

entity.Value = "my modified value"; 

db.SaveChanges(); 

但我想避免的第一個查詢,像這樣:

var entity = new Entity(); 
entity.Id = myId; 
entity.Value = "my modified value"; 
db.AddOrAttach(entity); 
db.SaveChanges(); 

有什麼相似?還是必須執行第一個查詢?

謝謝

+0

我的問題來看看這樣做一般的保存與EF:http://stackoverflow.com/questions/6018711/generic-way-to-check-if-entity-exists-in-entity-framework的結果這是(根據需要插入或更新)寫一個通用的保存方法。它很快變得混亂。 – Yuck

回答

2

不幸的是,您必須執行第一個查詢。

一個選擇是編寫一個執行T-SQL的存儲過程MERGE然後將其映射到一個函數導入,但這需要您將該實體的標量值作爲參數傳遞(並支持導航屬性完成),但它會完成你以後的事情。

+0

對於每個有此問題的表格,這都會造成太大的影響。如果這成爲性能問題,也許我會這樣做。 – willvv

0

我跑了編輯一些快速的測試代碼在MVC 3與EF 4,它似乎爲編輯與下面的代碼工作:

using (var context = new TestStackOverFlowEntities()) 
{ 
    Person p = new Person(); 
    p.Id = long.Parse(collection["Id"]); 
    p.FirstName = collection["FirstName"]; 
    p.LastName = collection["LastName"]; 
    context.People.Attach(p); 
    context.ObjectStateManager.ChangeObjectState(p, System.Data.EntityState.Modified); 
    context.SaveChanges(); 
    return RedirectToAction("Index"); 
} 

編輯:我有太多創建新的對象被選中,您需要改變這個

context.ObjectStateManager.ChangeObjectState(p, System.Data.EntityState.Added); 

當Id == 0 // ie ie new object。

快速和骯髒的代碼添加新是這樣的:

using (var context = new TestStackOverFlowEntities()) 
{ 
    Person p = new Person();       
    p.Id = 0; 
    p.FirstName = collection["FirstName"]; 
    p.LastName = collection["LastName"]; 
    context.People.Attach(p); 
    context.ObjectStateManager.ChangeObjectState(p, System.Data.EntityState.Added); 
    context.SaveChanges(); 
    return RedirectToAction("Index"); 
} 
+1

你不關注主要問題。您的回覆假定我知道是否要更新或插入。這個問題的整個想法是,我不知道會發生什麼。 – willvv

+0

「我有一種情況,我如果存在或添加一個新的,如果它不更新的實體。」 - 我給你的樣本可以處理這個問題,但是我做的假設是entityId對於新添加的將爲0,對於現有的對象爲> 0。這不適用於像GUID的東西。 –

+1

是的,但對我來說,我添加元素有一個外鍵的組合主鍵,因此它永遠不會是零。如果我有零,我可以使用它而不是我的代碼的第一個查詢。 – willvv

0

如果你只是試圖限制代碼澄清你的控制器:

db.Attach(model); 
db.SaveChanges(model); 

將更新,如果實體鍵存在,如果沒有創建。

+0

當然還有兩個疑問。 – shannon