Комментарии 10
Особенности EF не зависят от того используется он в Blazer или в обычном консольном приложении.
Это верно, но эта статья создана для тех, кто видит такое исключение впервые и именно на Blazor, так как например при создании API-сервера такие ошибки почти не возникают.
Здесь важно время существования контекста, создаваемого контейнером DI.
По этому критерию можно разделить на две группы:
консольки, MVC, web-api: один экземпляр на запрос, Singleton / Transient работают как ожидается;
blazor server, win form, win service: один экземпляр на приложение, Singleton/Transient эквивалентны.
Вы рассматриваете только вариант несколько контекстов на одной странице.
Гораздо чаще (и болезнее) вариант многопользовательской работы.
Поэтому использование фабрики в случае blazor server – практически безальтернативно.
Но при чем здесь конкретно blazor server? Напороться на такую проблему приходилось, я думаю, каждому, кто хоть когда использовал EF, хоть с blazor, хоть без него.
А по сути проблемы - ну да, а что вы хотели, если есть два контекста, которые работают с одними и теми же сущностями, вы получите конфликт.
Решение, в принципе, очевидно: не трекать сущности на чтение, держать один контекст и трекать всё него при выполнении обозначенной бизнес-операции.
И кстати, а почему вы не упомянули .AsNoTracking()?
Решение с одним контекстом не всегда можно использовать. Особенно если у вас большой проект и вам нужно разделить страницу на множество компонентов, для которых нужны свои данные из БД. Вытягивать все данные в родительском компоненте и после передавать их в качестве параметра - не всегда удобно. Например, если у вас вложенная структура и нужно передать данные 4-му дочернему компоненту. По поводу .AsNoTracking() - он выполняет тот же функционал, что и удаление контекста.
я правильно понял проблему?
что есть список айдишников userIds = [1,2,3]
делается рендер "карточек" передавая в параметре только userID
{loop}
<UserCard :userID ="i" >
{/loop}
А во время рендера этих карточек получается идет запрос в DB ?
onRender( db.getUserByID(i) )
И получается что если рендерить сразу 50 пользователей то это 50 запросов к бд вместо одного ?
Создавать на каждый метод или компонент, который может выполняться асинхронно, новый DbContext. Такой функционал можно реализовать через DbContextFactory
или IServiceScopeFactory
.
а зачем?
или у вас все классы бизнес логики синглтоны?
Проблемы работы с Entity Framework на Blazor Server