Хранение ObjectContext
в состоянии сеанса - это не то, что я считаю хорошей практикой, поскольку класс предназначен для инкапсуляции шаблона единицы работы - вы загружаете некоторые данные (сущности), изменяете их, зафиксируйте ваши изменения (которые отслеживаются UOW), и тогда вы закончите с этим. Объекты UOW не предназначены или не предназначены для длительного проживания.
Тем не менее, это можно сделать без каких-либо серьезных катастроф, вам просто нужно убедиться, что вы понимаете, что происходит за кулисами. Пожалуйста, прочитайте , если вы планируете делать это так, чтобы вы знали, во что вы ввязываетесь, и знали о компромиссах.
Я предполагаю, что объект Session будет завершен и настроен для сборки мусора по истечении сеанса пользователя, поэтому экземпляр будет расположен правильно.
Это на самом деле неточно, или, по крайней мере, кажется, что оно основано на том, как оно сформулировано. Окончание сеанса / выход из системы не приведет к немедленному удалению каких-либо элементов. Они будут в конечном итоге будут доработаны / утилизированы, но это зависит от сборщика мусора, и вы не можете контролировать, когда это произойдет. Самая большая потенциальная проблема здесь, если вам случится вручную открыть соединение на ObjectContext
, которое не будет закрываться автоматически - если вы не будете осторожны, вы можете получить утечку соединений с базой данных, что не будет обнаружено с регулярными юнит-тестами / интеграционными тестами / живыми тестами.
Количество данных, с которыми будет работать объектный контекст, невелико и не представляет проблемы для нашего достойного серверного оборудования, что касается кэширования во времени и относительно небольшого числа одновременных пользователей.
Просто имейте в виду, что рост неограничен. Если конкретный пользователь решит использовать ваш сайт в течение 12 часов подряд, выполняя различные запросы в течение всего дня, тогда контекст будет продолжать расти. ObjectContext
не имеет собственной внутренней «сборки мусора», он не удаляет кэшированные / отслеживаемые объекты, которые не использовались в течение длительного времени. Если вы уверены, что это не будет проблемой в зависимости от ваших вариантов использования, тогда хорошо, но главное, что должно вас беспокоить, это то, что вам не хватает контроля над ситуацией.
Еще одна проблема - безопасность потоков. ObjectContext
не является потокобезопасным. Доступ к сеансу обычно сериализуется, так что один запрос будет блокировать ожидание своего состояния сеанса, пока другой запрос для того же сеанса не будет завершен. Однако, если кто-то решит провести оптимизацию позже, в частности оптимизацию сеансов только для чтения на уровне страницы, запросы больше не будут удерживать исключительную блокировку, и у вас будет возможность столкнуться с различными условиями гонки или проблемами повторного входа. .
Последнее, но не менее важное, это, конечно, проблема многопользовательского параллелизма. ObjectContext
кэширует свои сущности во веки веков, пока не будет уничтожен. Если другой пользователь изменяет те же сущности самостоятельно ObjectContext
, владелец первой ObjectContext
никогда не узнает об этом изменении. Эти проблемы с устаревшими данными могут быть невероятно трудными для отладки, потому что вы можете наблюдать, как запрос отправляется в базу данных и возвращается с новыми данными, но ObjectContext
перезапишет его со старыми устаревшими данными, которые уже находятся в кэше. Это, по моему мнению, вероятно, самая важная причина, чтобы избежать долгоживущих ObjectContext
случаев; даже если вы думаете, что закодировали его для получения самых последних данных из базы данных, ObjectContext
решит, что он умнее вас, и вместо этого вернет вам старые сущности.
Если вы знаете обо всех этих проблемах и предприняли шаги по их устранению, хорошо. Но мой вопрос заключается в том, почему именно вы думаете, что сеансовый уровень ObjectContext
- это отличная идея? Создание ObjectContext
действительно очень дешевая операция, потому что метаданные кэшируются для всего домена приложения. Держу пари, что у вас либо ошибочное впечатление, что это дорого, либо вы пытаетесь реализовать сложные процессы с отслеживанием состояния на нескольких разных веб-страницах, и долгосрочные последствия последних намного хуже, чем какие-либо конкретные вред, который вы можете нанести, просто вставив ObjectContext
в сессию.
Если вы собираетесь продолжать и делать это в любом случае, просто убедитесь, что вы делаете это по правильным причинам, потому что для этого не так много веских причин. Но, как я уже сказал, это определенно возможно, и в результате ваше приложение не взорвется.
Обновление - для всех, кто рассматривает возможность отказа от голосования, поскольку «множественные запросы в одном сеансе могут вызвать проблемы с безопасностью потоков», ознакомьтесь с нижней частью Обзор состояния сеанса ASP.NET документация. Это не просто отдельные обращения состояния сеанса, которые сериализуются; любой запрос, который получает сеанс, сохраняет исключительную блокировку сеанса, который не освобождается до тех пор, пока весь запрос не будет выполнен. За исключением некоторых оптимизаций, которые я перечислил выше, в конфигурации по умолчанию невозможно, чтобы когда-либо было два одновременных запроса, содержащих ссылки на один и тот же локальный сеансный экземпляр ObjectContext
.
Я по-прежнему не буду хранить ObjectContext
в состоянии сеанса по нескольким причинам, перечисленным выше, но это не проблема безопасности потока, если вы не сделаете это.