Обновить свойства прикрепленного объекта с помощью значения базы данных по запросу

У меня есть классы сущностей, которые имеют целочисленное свойство (с именем 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. Клиентское приложение 1 загружает объект сущности с ROW_VERSION = 1, удаляет DbContext и сохраняет ссылку на этот объект сущности для дальнейшего редактирования.

  2. Клиентское приложение 2 загружает тот же объект сущности, упомянутый на шаге 1, изменяет свойство и сохраняет изменения. Это приводит к увеличению ROW_VERSION в БД (теперь это 2).

  3. Пользователь клиентского приложения 1 теперь изменяет некоторые свойства объекта сущности (который все еще находится в памяти с ROW_VERSION, равным 1).

  4. Прежде чем клиентское приложение 1 сохранит изменения, оно загружает некоторые другие объекты сущности для отображения и, в конечном итоге, снова выбирает рассматриваемый объект сущности (например, для просмотра внесенных изменений). Это вызывает запрос, результат которого будет содержать уже измененный объект сущности (поскольку он присоединен к DbContext до того, как фактический запрос будет отправлен в базу данных).

    И вот моя проблема: на этом этапе инфраструктура сущностей может сравнить ROW_VERSION прикрепленного объекта с ROW_VERSION объекта в фактическом результате запроса, обнаружить несоответствие и, например. создать исключение.

    Но вместо этого EF обрабатывает свойство ROW_VERSION как все другие свойства, которые могли быть изменены клиентом.

Поэтому я хочу, чтобы EF специально обрабатывал свойство ROW_VERSION и сравнивал его значения в каждом запросе, чтобы обнаруживать изменения, внесенные другими клиентами. Таким образом, я бы обнаруживал ситуации параллелизма раньше, чем при ожидании вызова SaveChanges.


person Hanns Echtleder    schedule 01.11.2012    source источник
comment
Мне потребовалось некоторое время, чтобы понять, что вы (вероятно) имеете в виду, что хотите, чтобы EF синхронизировал версию после фиксации записи. (А вы?) Но фиксация всегда будет приводить к конфликту параллелизма, если кто-то другой обновит запись, что должно предложить вам обновить запись из базы данных и разобраться с конфликтующими значениями. Или я упускаю вашу мысль?   -  person Gert Arnold    schedule 02.11.2012
comment
@Gert: Я не это спрашивал, я отредактировал свой вопрос, чтобы прояснить проблему.   -  person Hanns Echtleder    schedule 02.11.2012


Ответы (1)


Думаю, теперь я понимаю, но не вижу, как Entity Framework может вам здесь помочь.

  1. Оптимистичный параллелизм по определению — это стратегия обработки конфликтов при фиксации данных. Не при чтении данных. Таким образом, это будет отклонением от ожидаемого поведения, если ConcurrencyMode будет реализован таким образом (даже если он настраивается).
  2. Предположим, что классы сущностей EF можно настроить таким образом, чтобы они вели себя при чтении. Было бы очень сложно справиться со всеми возможными исключениями при получении списка этих сущностей или графа объектов, содержащего эти сущности. Следует ли откатить все чтение? Так что это, вероятно, было бы полезно только при чтении отдельных объектов сущностей. Это была бы очень (читай: слишком) детальная спецификация конфигурации.

Насколько я понимаю, если вам нужна эта система раннего предупреждения, вам придется программировать ее самостоятельно. Это должно включать некоторый запрос для чтения значения версии, поскольку Refresh с StoreWins (ObjectContext) или Reload (DbContext) всегда перезаписывает все значения.

person Gert Arnold    schedule 03.11.2012
comment
Спасибо за Ваш ответ. Я согласен, что мой вариант использования может быть не очень распространенным. Я по-прежнему думаю, что было бы удобно, если бы я мог настроить свойство объекта так, чтобы оно всегда обновлялось значением базы данных (независимо от проблемы оптимистичного параллелизма), но я вижу, что это, вероятно, не та функция, о которой обычно спрашивают пользователи ЭФ. - person Hanns Echtleder; 05.11.2012