Как управлять областью контекста БД в .NET Core при сбое SaveChanges () - PullRequest
0 голосов
/ 24 сентября 2019

У нас есть консольное приложение .NET Core, которое запускается из очереди служебной шины Azure.Насколько я понимаю, время жизни по умолчанию DbContext через DI составляет Scoped и что рекомендуется использовать DI и инфраструктуру для управления временем жизни вместо использования операторов using.Тем не менее, у нас есть следующий случай, когда мы вызываем SaveChanges(), он терпит неудачу, поэтому мы пытаемся вызвать его снова, чтобы записать журнал в базу данных.Какой рекомендуемый подход здесь?Странно использовать using, когда DI вводит контекст вызывающему классу.

try
{
    db.Add(new MyEntity());
    db.SaveChanges();
}
catch (Exception ex) // a constraint is violated
{
    db.Add(new LogEntity("Unable to save MyEntity"));
    db.SaveChanges(); // this fails because MyEntity is still in scope of the context
}

1 Ответ

1 голос
/ 24 сентября 2019

Насколько я понимаю, время жизни DbContext через DI по умолчанию - Scoped, и рекомендуется, чтобы DI и инфраструктура управляли временем жизни вместо использования using операторов.

Это не совсем точно, DI - это метод создания объектов, но вы все равно можете контролировать область действия объектов ... например, используя Ninject ( больше информации ):

// this would create a new MyType instance on every request
kernel.Bind<IMyType>().To<MyType>().InTransientScope();

// this would share MyType instance within the same Thread
kernel.Bind<IMyType>().To<MyType>().InThreadScope();

// this would share MyType instance within the same Web Request
kernel.Bind<IMyType>().To<MyType>().InRequestScope();

Относительно области применения DbContext см. Рекомендация Microsoft :

DataContext является легковесным и недорогим в создании.Типичное приложение LINQ to SQL создает экземпляры DataContext в области действия метода или в качестве члена недолговечных классов, представляющих логический набор связанных операций с базой данных.

Так что, как правило, рекомендуется делитьсятот же экземпляр DbContext в том же методе ... здесь исключение - логирование .Не стоит смешивать логгер DbContext с операциями, которые он регистрирует.Ведение журнала должно быть независимым от этих операций ... многие предпочитают регистрировать свое сообщение в текстовом файле, электронной почте, БД ... если вы хотите использовать БД для ведения журнала, вы можете рассмотреть возможность использования другой БД для вашего сообщения журнала.Также рассмотрите возможность использования каркасов журналирования, таких как Serilog , NLog и т. Д.

...