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

相关问题