У меня есть классы сущностей, которые имеют целочисленное свойство (с именем ROW_VERSION) с ConcurrencyMode, для которого установлено значение «Fixed» для оптимистичной проверки параллелизма. Я увеличиваю значение этого столбца в коде своего приложения перед сохранением объекта этого типа (поэтому для StoreGeneratedPattern установлено значение None). Это хорошо работает при сохранении изменений.
Теперь я также хотел бы обнаружить ошибку параллелизма, когда у меня есть ранее загруженный объект (с ROW_VERSION = x), и я создаю новый DbContext, присоединяю этот объект и выдаю запрос с использованием этого объекта. Проблема в том, что если ROW_VERSION была увеличена другим клиентским приложением (ROW_VERSION = x + 1), это не обнаруживается во время моего запроса, потому что значение прикрепленного объекта имеет очевидный приоритет (что полностью имеет смысл для общих значений столбцов). ).
С другой стороны, для моего столбца проверки параллелизма было бы неплохо, если бы EF обновил значение текущим значением базы данных, чтобы я мог сравнить его с ожидаемым значением. В качестве альтернативы допустимо исключение, вызванное выполнением запроса.
Я использую Entity Framework 4.3 с .NET 4.0.
Изменить (в ответ на комментарий Герта Арнольда):
Я пытаюсь прояснить свою проблему немного больше...
Примечания о том, как мое приложение работает в целом:
Существует древовидное представление, показывающее мои доступные объекты сущностей, и при выборе одного из них полная сущность загружается из БД для отображения в подробном представлении, где ее можно редактировать.
Модификации объекта сущности не сохраняются сразу, а кэшируются в памяти, поэтому модификации различных объектов сущности могут накапливаться и сохраняться все вместе, когда пользователь нажимает кнопку сохранения.
DbContext создаются отдельно для запросов и сохранения изменений (т.е. у меня нет одного и того же DbContext все время, но они создаются по мере необходимости).
Когда объект сущности загружается для отображения в подробном представлении, все ранее измененные объекты сущности (кэшированные) присоединяются к DbContext, который сначала используется для запроса. Затем выдается фактический запрос. Поэтому, если я запрашиваю объект сущности, который был изменен до того, как я получу измененную версию в качестве результата, а не версию из базы данных (которая могла измениться за это время).
Итак, вот пример, который показывает мою проблему:
Клиентское приложение 1 загружает объект сущности с ROW_VERSION = 1, удаляет DbContext и сохраняет ссылку на этот объект сущности для дальнейшего редактирования.
Клиентское приложение 2 загружает тот же объект сущности, упомянутый на шаге 1, изменяет свойство и сохраняет изменения. Это приводит к увеличению ROW_VERSION в БД (теперь это 2).
Пользователь клиентского приложения 1 теперь изменяет некоторые свойства объекта сущности (который все еще находится в памяти с ROW_VERSION, равным 1).
Прежде чем клиентское приложение 1 сохранит изменения, оно загружает некоторые другие объекты сущности для отображения и, в конечном итоге, снова выбирает рассматриваемый объект сущности (например, для просмотра внесенных изменений). Это вызывает запрос, результат которого будет содержать уже измененный объект сущности (поскольку он присоединен к DbContext до того, как фактический запрос будет отправлен в базу данных).
И вот моя проблема: на этом этапе инфраструктура сущностей может сравнить ROW_VERSION прикрепленного объекта с ROW_VERSION объекта в фактическом результате запроса, обнаружить несоответствие и, например. создать исключение.
Но вместо этого EF обрабатывает свойство ROW_VERSION как все другие свойства, которые могли быть изменены клиентом.
Поэтому я хочу, чтобы EF специально обрабатывал свойство ROW_VERSION и сравнивал его значения в каждом запросе, чтобы обнаруживать изменения, внесенные другими клиентами. Таким образом, я бы обнаруживал ситуации параллелизма раньше, чем при ожидании вызова SaveChanges.