1

Я использую Mssql как db и 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) объекты могут быть изменены или удалены с погрузил лицо Refresh 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

Эта ошибка является побочным эффектом оптимизационного параллелизма 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 оптимистической параллельности here, что объясняет более подробно, почему ваши получать эту ошибку, и какие шаги можно предпринять для борьбы с ним.

+0

спасибо за комментарий РПС, но это не проблема оптимистичного параллелизма. Я работаю на локальном компьютере разработчика, не статически не статирую, это не проблема. Контекст создается с помощью этого метода: http://dotnetslackers.com/articles/ado_net/Managing -Entity-Framework-ObjectContext-lifespan-and-scope-in-n-layered-ASP-NET-applications.aspx, используя обычный способ создания контекста, который ничего не меняет. – Adir 2010-12-16 14:39:10

Смежные вопросы