我应该在删除之前检查一行是否存在?
问题描述:
我使用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命令删除行。
什么是更好的做法?
答
该错误是实体框架乐观并发性的副作用。
基本上,其他人可能删除了您检索它之间的记录。或者也许你在代码之前已经对实体做了些什么。
尝试在隔离环境(例如单元测试)中运行它以查看您是否仍然遇到问题。
是的,你可以发挥它的安全,并再次获得记录,或者你可以使用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,其中更详细地解释为什么你收到这个错误讯息,并且可以做哪些措施来应对。
感谢您的评论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
看看文章 - 错误那个arti cle与你的完全一样。您是否尝试在单元测试(单独)中运行上述代码?另外 - 你提供的那篇文章中的哪个方法是你实例化上下文的? (该文章中有多种方法) – RPM1984 2010-12-16 20:42:27
我已经使用了UnitOfWorkScope方法,但这不是问题。即使我使用旧方式实例化上下文(MyContext context = new MyContext()),仍然会显示相同的错误。我不认为它与并发有关,错误显示是因为我试图删除上下文中不存在的对象。 – Adir 2010-12-17 11:54:11