1

我使用 Mssql 作为数据库,使用 EF4 作为 ORM/DAL。
我的问题是关于以下代码:

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 命令简单地删除该行。

什么是更好的做法?

4

1 回答 1

0

该错误是 Entity Framework 的乐观并发的副作用。

基本上,其他人可能在您检索记录之间删除了该记录。或者,也许您在该代码之前对实体做了一些事情。

尝试在隔离环境中运行它(例如单元测试),看看您是否仍然遇到问题。

是的,您可以安全地使用它并再次获取记录,或者您可以使用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 乐观并发的优秀文章,它更详细地解释了为什么会出现该错误,以及可以采取哪些步骤来应对它。

于 2010-12-15T22:38:00.167 回答