Язык программирования C#9 и платформа .NET5
Часть 409 из 642 Информация о книге
static void SampleSaveChanges(){// Фабрика не предназначена для такого использования,// но это демонстрационный кодvar context = new ApplicationDbContextFactory().CreateDbContext(null);// Внести какие-нибудь изменения.context.<b>SaveChanges()</b>;}В оставшемся материале главы (и книги) вы обнаружите много примеров сохранения изменений.
Поддержка транзакций и точек сохранения
Исполняющая среда EF Core помещает каждый вызов
внутрь неявной транзакции, использующей уровень изоляции базы данных. Чтобы добиться большей степени контроля, можете включить экземпляр производного классаSaveChanges()/SaveChangesAsync()в явную транзакцию. Для выполнения явной транзакции создайте транзакцию с применением свойстваDbContextкласса, производного отDatabase. Управляйте своими операциями обычным образом и затем предпримите фиксацию или откат транзакции. Ниже приведен фрагмент кода, где все демонстрируется:DbContextusing var trans = context.Database.BeginTransaction();try{// Создать, изменить, удалить запись.context.SaveChanges();trans.Commit();}catch (Exception ex){trans.Rollback();}В версии EF Core 5 были введены точки сохранения для транзакций EF Core. Когда вызывается метод
, а транзакция уже выполняется, исполняющая среда EF Core создает в этой транзакции точку сохранения. Если вызов терпит неудачу, то откат транзакции происходит в точку сохранения, а не в начало транзакции. Точками сохранения можно также управлять в коде, вызывая методыSaveChanges()/SaveChangesAsync()иCreateSavePoint()для транзакции:RollbackToSavepoint()using var trans = context.Database.BeginTransaction();try{// Создать, изменить, удалить запись.trans.CreateSavepoint("check point 1");context.SaveChanges();trans.Commit();}catch (Exception ex){trans. RollbackToSavepoint("check point 1");}Транзакции и стратегии выполнения
В случае активной стратегии выполнения (как при использовании
) перед созданием явной транзакции вы должны получить ссылку на текущую стратегию выполнения, которая применяется EF Core. Затем вызовите на этой стратегии методEnableRetryOnFailure(), чтобы создать явную транзакцию:Execute()var strategy = context.Database.CreateExecutionStrategy();strategy.Execute(() =>{using var trans = context.Database.BeginTransaction();try{actionToExecute();trans.Commit();}catch (Exception ex){trans.Rollback();}});События SavingChanges/SavedChanges
В версии EF Core 5 появились три новых события, которые инициируются методами
. СобытиеSaveChanges()/SaveChangesAsync()запускается при вызовеSavingChanges, но перед выполнением операторов SQL в хранилище данных, а событиеSaveChanges()— после завершения работы методаSavedChanges. В следующем (простейшем) коде демонстрируются события и их обработчики в действии:SaveChanges()public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options): base(options){SavingChanges += (sender, args) =>{Console.WriteLine($"Saving changes for {((DbContext)sender).Database.GetConnectionString()}");};SavedChanges += (sender, args) =>{Console.WriteLine($"Saved {args.EntitiesSavedCount} entities");};SaveChangesFailed += (sender, args) =>{Console.WriteLine($"An exception occurred! {args.Exception.Message}entities");};}Класс DbSet<T>
Для каждой сущности в своей объектной модели вы добавляете свойство типа
. КлассDbSet<T>представляет собой специализированную коллекцию, используемую для взаимодействия с поставщиком баз данных с целью получения, добавления, обновления и удаления записей в базе данных. Каждая коллекцияDbSet<T>предлагает несколько основных служб для взаимодействия с базой данных. Любые запросы LINQ, запускаемые в отношении классаDbSet<T>, транслируются поставщиком базы данных в запросы к базе данных. В табл. 22.2 описан ряд основных членов классаDbSet<T>.DbSet<T>