Это помогает воспринимать контексты EF и их локальное кэширование, особенно как недолговечные. Когда вы читаете сущность, «продолжительность жизни» этой сущности следует рассматривать как соответствующую продолжительности жизни DbContext, который ее создал. По истечении этого срока жизни фактически считается, что объект подобен любой другой потенциально устаревшей копии данных. Даже в течение этого срока службы он не синхронизируется с основным источником данных, поэтому смысл в том, когда вызывается SaveChanges
. Кэширование EF больше связано со сценарием: «Я собираюсь загрузить некоторые сущности, и эти сущности ссылаются на другие сущности. Когда код перебирает сущности, когда он сталкивается со ссылкой на что-то другое, EF проверяет посмотрим, загружено ли это что-то еще, и подайте его перед отправкой в БД. " Поэтому в этом смысле долгоживущий DbContext является плохой вещью, поскольку некоторые из этих кэшированных данных могут быть довольно старыми и устаревшими, а поскольку DbContext загружает больше данных, просеивание через эти отслеживаемые объекты становится медленнее, а контекст потребляет больше памяти.
В веб-приложениях DbContext обычно ограничивается одним запросом или короче этого. (Единица работы) Это означает, что изменения по одновременно обрабатываемым запросам не уведомляются об изменениях друг друга, и ни один запрос не видит изменений, внесенных другими источниками, между моментом, когда эти контексты запроса загружали свои данные и готовились к сохранению. EF может быть осведомлен о том, что проверять наличие одновременных изменений, обычно это временная метка версии строки, и может блокировать обновление в случае неудачной проверки. Кроме того, именно разработчик должен определить, какое действие предпринять. Это часто означает обнаружение ошибки параллелизма и последующую передачу соответствующему обработчику для регистрации деталей и уведомления пользователя. Это может быть сценарий «первым выиграл», когда пользователь получает уведомление о том, что его изменения не пройдены, и пытается снова; (с предоставленными обновленными данными) Сценарий «последние выигрыши», когда пользователю предлагается внести изменения, но они могут перезаписать; (и, мы надеемся, зарегистрировали событие в случае возникновения споров / вопросов) Или слияние, при котором система проверяет изменения и предоставляет подробную информацию о любых конфликтах и изменениях, чтобы пользователь мог просмотреть и отрегулировать / принять / или отменить свое обновление.
EF может помочь обнаружить это, но в конечном итоге разработчик должен написать, что с этим делать.
С точки зрения обнаружения одновременных правок по мере их возникновения, это требует преднамеренного кодирования для таких вещей, как передача изменений между сеансами (публикация / подписка), когда каждый сеанс прослушивает обновления для сущностей, над которыми он активно работает, и передает изменения сущностям по мере обновляет их. Обнаружение возможных других изменений данных из других источников означает другой процесс для прослушивания обновлений БД (помимо тех изменений, которые он уже знает о внесенных системой) и рассылка уведомлений об этих изменениях любым активным сеансам. Конечно, очень здорово видеть работу в действии, но затраты и сложность, которые она вносит, должны быть оправданы не только решением проблем параллелизма при сохранении. :)