1

我使用Mssql作爲ORM/DAL的db和EF4。
我的問題是關於下面的代碼:我應該在刪除之前檢查一行是否存在?

public static void DeleteBuilding(int buildingId, int countryId) 
{ 
    PlayerBuilding playerBuilding = new PlayerBuilding() 
    { 
     CountryID = countryId, 
     BuildingID = buildingId 
    }; 
    Entities.PlayerBuildings.Attach(playerBuilding); 
    Entities.PlayerBuildings.DeleteObject(playerBuilding); 
    Entities.SaveChanges(); 
} 

如果行存在這個作品非常好,如果不是我得到一個異常(商店更新,插入或刪除語句影響行的一個意外的數(0)實體可能已被修改或刪除,因爲實體加載刷新ObjectStateManager項
我應該做一個往返到數據庫中,以檢查是否存在這樣的行:。

public static void DeleteBuilding(int buildingId, int countryId) 
{ 
    PlayerBuilding playerBuilding = (from p in Entities.PlayerBuildings 
            where p.BuildingID == buildingId && p.CountryID == countryId 
            select p).FirstOrDefault(); 
    if (playerBuilding != null) 
    { 
     Entities.PlayerBuildings.DeleteObject(playerBuilding); 
     Entities.SaveChanges(); 
    } 
} 

我認爲額外往返是不必要的,因爲如果沒有EF,使用純SQL,我可以簡單地用一個DELETE命令刪除行。

什麼是更好的做法?

回答

0

該錯誤是實體框架樂觀併發性的副作用。

基本上,其他人可能刪除了您檢索它之間的記錄。或者也許你在代碼之前已經對實體做了些什麼。

嘗試在隔離環境(例如單元測試)中運行它以查看您是否仍然遇到問題。

是的,你可以發揮它的安全,並再次獲得記錄,或者你可以使用ObjectContext.Refresh

public static void DeleteBuilding(int buildingId, int countryId) 
{ 
    PlayerBuilding playerBuilding = new PlayerBuilding() 
    { 
     CountryID = countryId, 
     BuildingID = buildingId 
    }; 

    try 
    { 
     Entities.PlayerBuildings.Attach(playerBuilding); 
     Entities.PlayerBuildings.DeleteObject(playerBuilding); 
     Entities.SaveChanges(); 
    } 
    catch (OptimisticConcurrencyException) 
    { 
     Entities.Refresh(RefreshMode.ClientWins, playerBuilding); 
     Entities.SaveChanges(); 
    } 
} 

在一個側面說明 - 也許是因爲你的方法是靜態?你如何實例化你的上下文?我希望你不要使用單身。 :(

有一個優秀文章EF樂觀併發here,其中更詳細地解釋爲什麼你收到這個錯誤訊息,並且可以做哪些措施來應對。

+0

感謝您的評論RPM,但這不是一個樂觀的併發問題,我正在開發一個本地開發人員計算機,並非試圖使用靜態方法,也不是問題所在。上下文使用此方法實例化:http://dotnetslackers.com/articles/ado_net/Managing -Entity-Framework-ObjectContext-lifetime-and-scope-in​​-n-layered-ASP-NET-applications.aspx。使用正常的方式來實例化上下文而不改變任何東西。 – Adir 2010-12-16 14:39:10

+0

看看文章 - 錯誤那個arti cle與你的完全一樣。您是否嘗試在單元測試(單獨)中運行上述代碼?另外 - 你提供的那篇文章中的哪個方法是你實例化上下文的? (該文章中有多種方法) – RPM1984 2010-12-16 20:42:27

+0

我已經使用了UnitOfWorkScope方法,但這不是問題。即使我使用舊方式實例化上下文(MyContext context = new MyContext()),仍然會顯示相同的錯誤。我不認爲它與併發有關,錯誤顯示是因爲我試圖刪除上下文中不存在的對象。 – Adir 2010-12-17 11:54:11

相關問題