2017-08-10 104 views
0

假設我有兩個實體E1E2都共享相同的Code值。假設我想刪除第一和插入下一個:使用實體框架刪除和插入實體

Item.Delete(E1); 
Item.Insert(E2); 
Item.Save(); 

public void Delete(Entity E) 
{ 
    var existingEntity = _context.EntityTable.SingleOrDefault(s => s.Code == E.Code); 
    _context.EntityTable.Remove(existingEntity); 
} 

public void Insert(Entity E) 
{ 
    var existingEntity = _context.EntityTable.FirstOrDefault(s => s.Code == E.Code); 
    if (existingEntity != null){ 
     throw new ArgumentException("Item alread exists.") 
    } 

    var newEntity = CreateDbEntity(E); // Create Db Entity just convert the type. Nothing much here. 
    _context.EntityTable.Add(newEntity); 
} 

public void Save() 
{ 
    _context.SaveChanges(); 
} 

這裏的問題是,當我在_contextEntityTable刪除E1,即不會立即反映到我保存。因此,操作將失敗,因爲E1仍然存在,插入E2不成功。有沒有解決這個問題,EntityTable確實反映了所做的更改?

+1

爲什麼你不把獨特的條件留給SQL而不檢查代碼? –

+0

在您查詢是否存在以及您對SaveChanges()的調用之間,還可以通過另一個進程或線程插入。不要在代碼中這樣做。 – CodeCaster

+0

刪除>保存>插入>保存..大聲笑 – niksofteng

回答

0

它看起來像你只是有一個操作順序錯誤這可能不是最有效的方式,但它應該照顧你的問題。

Item.Delete(E1); 
Item.Save(); 
Item.Insert(E2); 
Item.Save(); 

以該順序調用它們。

或者您可以將save方法添加到您的刪除和插入方法中,以便它可以保存每個方法,您只需使用兩行。

public void Delete(Entity E) 
{ 
    var existingEntity = _context.EntityTable.SingleOrDefault(s => s.Code == E.Code); 
    _context.EntityTable.Remove(existingEntity); 
    Save() 
} 

public void Insert(Entity E) 
{ 
    var existingEntity = _context.EntityTable.FirstOrDefault(s => s.Code == E.Code); 
    if (existingEntity != null){ 
     throw new ArgumentException("Item alread exists.") 
    } 

    var newEntity = CreateDbEntity(E); // Create Db Entity just convert the type. Nothing much here. 
    _context.EntityTable.Add(newEntity); 
    Save() 
} 

public void Save() 
{ 
    _context.SaveChanges(); 
} 

,然後你可以這樣調用它

Item.Delete(E1); 
Item.Insert(E2); 

希望這有助於!如果不讓我知道,我會刪除答案(我不得不使用答案,因爲我不能評論50代表,否則我會在回答之前使用評論來獲得更清晰的答案)乾杯!

+0

謝謝。總的來說問題是我想避免兩次去DB。我爲Repo使用UOW模式,以便業務邏輯對象不需要多次訪問數據庫以插入不同的對象。 – Husain

1

每次操作後簡單呼叫SaveChanges

你想進行交易,當你初始化你的背景下(這樣可以確保這兩個操作都執行):然後

_context = new FooEntities(); 
_transaction = _context.Database.BeginTransaction(); 

Save方法將提交替代交易:

_transaction.Commit(); 

它將不會損害處理上下文和交易,但我相信你已經這樣做了;)


在一個側面說明,因爲你扔反正異常:

if (existingEntity != null){ 
    throw new ArgumentException("Item alread exists.") 
} 

爲什麼不能創造的Code列unique constraint?這樣數據庫會拋出異常;)

+0

謝謝。我試圖避免爲此往返兩次DB。唯一的約束條件適用於這個簡單的例子,但不適用於我的情況,因爲我有一個軟刪除。有了這個約束,我將不得不解密從數據庫中獲得的異常,以便向API用戶返回有用的消息。 – Husain

+0

您可以在多列(例如Code&IsDeleted)之上設置uniuqe限制。使用[ExceptionFilters](https://stackoverflow.com/a/34813242/2441442),使用C#6可以輕鬆實現更好的異常。關於往返:典型的閱讀是昂貴的閱讀,因爲這比寫作發生得多; @Husain –