НС>Ты не понял. Я не предлагаю делать контекст синглтоном, я наоборот предлагаю его создавать по месту явно.
А зачем явно/руками/ETC? Чем серийный велосипед плох? Вот поверьте, без изобретений новых велосипедов хватает где потрещать мозгами и попрограмировать.
P.S. Я в другой ветке написал, что ошибку нашли
Re: .NET 5.0, EF6, DependencyInjection и асинхронный WebAPI
Здравствуйте, Yuri Abele, Вы писали:
YA>Всем привет!
YA>
Имеется:
YA>Написанный на .NET 4.8, NancyFX 1.x и EF 6.0 проект. YA>В роли базы данный — MSSQL. YA>Все API (NancyFX), DAL и EF6 вызовы асинхронны (async+await). YA>Dependency Injection для DbContext — Request Singleton, т.к. активно используются транзакции. YA>Всё хостится в IIS, Application Poll — integrated. YA>Всё работает как часики уже три года и под большой нагрузкой с кучей активных пользователей.
YA>
Потребовалось:
YA>Портировать всё на .NET Core. YA>В связи с тем, что время еще есть, а .NET 5.0 уже на подходе, приняли решение портировать таким образом: YA>.NET 4.8 => .NET 5.0 YA>.EF6 => EF6 YA>NancyFX => WebAPI YA>TinyIoCContainer => Microsoft.Extensions.DependencyInjection YA>Всё хостится в IIS в in-process конфигурации (Application Poll — integrated).
YA>Всё вроде портировалось, но начались ... YA>
Проблемы:
YA>Если при Reqest-е к WebAPI в EF один единственный async запрос (linq to entities), то всё нормально. Даже если парочка в цепочке, то тоже отрабатывает. YA>Но если же там цепочка async вызовов, то где-то в середине цепочки (точное место от вызова к вызову "плавает"), linq to entities запросы вылетают с exception-ом, в котором говорится, что к этому моменту DbContext уже в состоянии disposed. YA>Эксперимента ради пробовали перевести запросы в синхронное выполнение — ошибки пропадают, на нам надо асинхронное. YA>Добавив к DbContext уникальный идентификатор (создаем GUID в конструкторе), и выводя его в лог при вызове конструктора и при dispose видим, что: YA>- DbContext действительно Request Singleton YA>- Log-сообщение из dispose появляется после возникновения, описанного выше, exception-а.
YA>Мы даже не знаем на что грешить — на Dependency Injector, на .NET Core (.NET 5.0), на хостинг в IIS, или еще на что! YA>Кто-то сталкивался с такой проблемой?
Dispose у DbContext в Core зависит от БД под ним. На одних и тех же сценариях, по моему Postres, его диспозит без спроса. А MSSQL и MySQL — нет. Но это не точно. Возможно память меня подвела. Но я уверен на 100% что диспозом DBContext рулит БД под ним. Я пару дет назад с таким сталкивался. Намучался я тогда с этим левым Dispose. но не долго, потому что были с самого начала тесты с реальными БД.
Покрывайте тестами с реальными БД. Иначе долго будете гадать. Это не сложно.
И покажите что вы инжектитам в Startup? Попробуйте DbConnection и Transaction руками создавать и передавать их в конструктор DbContext.
В любом случае покрывайте тестами с реальными БД. Иначе долго будете гадать. Это не сложно.
И про транзакции на все http-реквесты вам тут правильно написали. У вас в каждой операции бизнеслогики свой уровень изоляции. Зачем вам все грести под одну гребенку?
Так не делается. мучайтесь теперь
Re[6]: .NET 5.0, EF6, DependencyInjection и асинхронный WebAPI
Здравствуйте, Yuri Abele, Вы писали:
YA>А зачем явно/руками/ETC? Чем серийный велосипед плох?
Контекс EF представляет собой завершенный паттерн UnitOfWork, проект рано или поздно разрастается до такой степени, что по бизнес правилам требуется рядом второй экземпляр такого действа, например в распределенной транзакции, когда в одном собираем Entity в случае успеха, а в другом Entity для неудачи, и по завершению всей логики просто вызываем SaveChangesAsync в одного из двух.
Re[3]: .NET 5.0, EF6, DependencyInjection и асинхронный WebAPI
Здравствуйте, Yuri Abele, Вы писали: YA>А к чему вы эту очевидную истину?
Топик не проблема кор. Кор простой, но не примитивный.
Проблемы исчезают по мере изучения предмета.
И странно, почему нанси фикх, штука прикольная, но со своими тараканами.
нельзя от программиста скрывать http-слой совсем, потом не достать данные заголовков. Так к слову.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[7]: .NET 5.0, EF6, DependencyInjection и асинхронный WebAPI
Здравствуйте, alexsoff, Вы писали:
A>Здравствуйте, Yuri Abele, Вы писали:
YA>>А зачем явно/руками/ETC? Чем серийный велосипед плох? A>Контекс EF представляет собой завершенный паттерн UnitOfWork, проект рано или поздно разрастается до такой степени, что по бизнес правилам требуется рядом второй экземпляр такого действа, например в распределенной транзакции, когда в одном собираем Entity в случае успеха, а в другом Entity для неудачи, и по завершению всей логики просто вызываем SaveChangesAsync в одного из двух.
Странный какой-то подход ...
Проект уже и так большущий — такое не требуется. А бизнес логика вокрук создаваемого лизингово договора в котором в разных местах бизнес процесса участвуют 5 пользователей (ролей).
И есть у нас и сохранение промежуточных состояний и электронное одобрение (on-line!) неограниченного количества "одобрятелей" и сложные вычесления EURO-цифорок и, при плохом раскладе, откат к изначальному состоянию.
Данные тоже лежат, частично у нас в портале на ЬЫЫЙД, частично в Back Office на AS400/DB2, частично (для частичных денежных вычислений) чёрте где на Web Service налогового адвоката.
И НИКОГДА не возникала вести двойную бухгалтерию /шучу! / — я про два DbContext-а
Re[2]: .NET 5.0, EF6, DependencyInjection и асинхронный WebA
VC>И про транзакции на все http-реквесты вам тут правильно написали. У вас в каждой операции бизнеслогики свой уровень изоляции. Зачем вам все грести под одну гребенку?
Кто сказал про "все"?! Только те итолько в тот момент, когда надо. Только сама цепочка изменений в транзакции вся подкотовительная часть вне оной.
VC>Так не делается. мучайтесь теперь
Да с чего Вы взяли?! У нас всё прекрасно работает на боевом сервере.
Сложность была, как теперь выяснилось (я еще вчера в другом сообщениии написал
Здравствуйте, Yuri Abele, Вы писали:
YA>Проект уже и так большущий — такое не требуется. А бизнес логика вокрук создаваемого лизингово договора в котором в разных местах бизнес процесса участвуют 5 пользователей (ролей). YA>И есть у нас и сохранение промежуточных состояний и электронное одобрение (on-line!) неограниченного количества "одобрятелей" и сложные вычесления EURO-цифорок и, при плохом раскладе, откат к изначальному состоянию. YA>Данные тоже лежат, частично у нас в портале на ЬЫЫЙД, частично в Back Office на AS400/DB2, частично (для частичных денежных вычислений) чёрте где на Web Service налогового адвоката. YA>И НИКОГДА не возникала вести двойную бухгалтерию /шучу! / — я про два DbContext-а
Да я и не спорю что это все можно написать и с одним dbContext.
Но я отказался от Scoped действий, когда написал что -то типа.
public class MyController{
private DbContext _myContext; //инициализируем в конструктореprivate IMyBusinessLogic _businessLogic;//инициализируем в конструкторе
//.ctor
//Какой-то actionpublic async Task<IAsyncResult> DoByBusinessRule(){
_myContext.Set<MyEntity>.Add(new MyEntity());
if(_businessLogic.DoCheck()){
await_myContext.SaveChanges();
}
}
}
Вроде все хорошо, но до того, как в DoCheck появится свой dbcontext (который Scoped) с вызовом await_myContext.SaveChanges() и тогда у нас логика внешнего кода будет нарушена.
public class MyBusinessLogic:IMyBusinessLogic{
private DbContext _myContext; //инициализируем в конструктореpublic async Task<bool> DoCheck(){
await _myContext.SaveChanges();
}
}
Поэтому при активном использовании всяких UnitOfWork с хранимым состоянием в Scoped режиме — все-таки использую разные фабрики с OnDemand созданием контекста с принудительной проверкой на Transient конфигурацию (а то были такие случае, когда кто-то решал в конфигурации для "ускорения" поменять настройки dbContext на Scoped режим).
Re[2]: .NET 5.0, EF6, DependencyInjection и асинхронный WebAPI
Здравствуйте, Yuri Abele, Вы писали:
YA>Коллега, который начинал всё это портирование, в самом начале, в контроллере WebAPI, в вызванном route-ингом асинхронном методе, при вызове асинхронного-же метода сервиса (DAL), умудрился забыть поставить await.
А варнинга не было?
Re[6]: .NET 5.0, EF6, DependencyInjection и асинхронный WebAPI
Здравствуйте, Yuri Abele, Вы писали:
НС>>Ты не понял. Я не предлагаю делать контекст синглтоном, я наоборот предлагаю его создавать по месту явно. YA>А зачем явно/руками/ETC?
Я уже отвечал на этот вопрос.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: .NET 5.0, EF6, DependencyInjection и асинхронный WebA
Здравствуйте, Flem1234, Вы писали:
F>Здравствуйте, Yuri Abele, Вы писали:
YA>>Коллега, который начинал всё это портирование, в самом начале, в контроллере WebAPI, в вызванном route-ингом асинхронном методе, при вызове асинхронного-же метода сервиса (DAL), умудрился забыть поставить await.
F>А варнинга не было?
Самое что прикольное — ни сам VS, ни ReSharper не ругнулись.
Только в Run-time, каким-то волшебным образом, async запросы к БД запускались и часть даже успевала отработать, а потом остальные натыкались на то, что DbContext уже disposed.
Re[4]: .NET 5.0, EF6, DependencyInjection и асинхронный WebA
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Здравствуйте, Yuri Abele, Вы писали:
YA>>Да с чего Вы взяли?! У нас всё прекрасно работает на боевом сервере.
НС>Как оказалось — таки у вас ошибка была, и то что вы не заметили проблем — то ли случайность, то ли отсутствие привычки просматривать логи на проде.
О великий гуру, програмирующий без ошибок, научи пользоваться логами — щютка, киргуду.
Коллега, вот честно, не надо оприори, и тем более, не зная людей и не видя самого решения, кидаться гнилушками. Такое отношение отбивает у людей вообще что-либо спрашивать у других.
Почитайте Карнеги (который психолог) ...
А еще перечитайте изначальный постинг — поиск по ключевому слову "портирование"