Язык программирования C#9 и платформа .NET5
@p2=0x0000000000008665exec sp_executesql N'SELECT TOP(1) [i].[Id], [i].[Color],[i].[IsDrivable], [i].[MakeId],[i].[PetName], [i].[TimeStamp]FROM [dbo].[Inventory] AS [i]WHERE [i].[Id] = @__p_0',N'@__p_0 int',@__p_0=1Удаление записей
Одиночная сущность помечается для удаления путем вызова
наRemove()или установки ее состояния вDbSet<T>. Список записей помечается для удаления вызовомDeletedнаRemoveRange(). Процесс удаления будет вызывать эффекты каскадирования для навигационных свойств на основе правил, сконфигурированных в методеDbSet<T>(и регламентированных соглашениями EF Core). Если удаление не допускается из -за политики каскадирования, тогда генерируется исключение.OnModelCreating()Состояние сущности
Когда метод
вызывается на отслеживаемой сущности, свойствоRemove()устанавливается вEntityState. После успешного выполнения оператора удаления сущность исключается изDeletedи состояние изменяется наChangeTracker. Обратите внимание, что сущность по-прежнему существует в вашем приложении, если только она не покинула область видимости и не была подвержена сборке мусора.DetachedУдаление отслеживаемых сущностей
Процесс удаления зеркально отображает процесс обновления. Как только сущность начала отслеживаться, вызовите
на контексте и затем вызовитеRemove(), чтобы удалить запись из базы данных:SaveChanges()[Fact]public void ShouldRemoveACar(){ExecuteInATransaction(RunTheTest);void RunTheTest(){var carCount = Context.Cars. Count();var car = Context.Cars.First(c => c.Id == 2);Context.Cars.Remove(car);Context.SaveChanges();var newCarCount = Context.Cars.Count();Assert.Equal(carCount - 1, newCarCount);Assert.Equal(EntityState.Detached,Context.Entry(car).State);}}После вызова
экземпляр сущности все еще существует, но больше не находится вSaveChanges(). СостояниемChangeTrackerбудетEntityState. Вот как выглядит выполняемый код SQL:Detachedexec sp_executesql N'SET NOCOUNT ON;DELETE FROM [dbo].[Inventory]WHERE [Id] = @p0 AND [TimeStamp] = @p1;SELECT @@ROWCOUNT;',N'@p0 int,@p1 varbinary(8)',@p0=2,@p1=0x0000000000008680Удаление неотслеживаемых сущностей
Неотслеживаемые сущности способны удалять записи таким же способом, каким они могут обновлять записи. Удаление производится вызовом
или установкой состояния вRemove()/RemoveRange()и последующим вызовомDeleted.SaveChanges()В показанном ниже тесте сначала читается запись как неотслеживаемая и на основе записи создается новый экземпляр класса
. Затем либо устанавливается состояние вCar, либо применяется методDeletedклассаRemove()(в зависимости от того, какая строка кода закомментирована) и вызываетсяDbSet<T>. Все дополнительные контексты нужны для обеспечения точности теста и отсутствия пересечения между контекстами:SaveChanges()[Fact]public void ShouldRemoveACarUsingState(){ExecuteInASharedTransaction(RunTheTest);void RunTheTest(IDbContextTransaction trans){var carCount = Context.Cars.Count();var car = Context.Cars.AsNoTracking().First(c => c.Id == 2);var context2 = TestHelpers.GetSecondContext(Context, trans);// Либо модифицировать состояние, либо вызвать Remove().context2.Entry(car).State = EntityState.Deleted;// context2.Cars.Remove(car);context2.SaveChanges();var newCarCount = Context.Cars.Count();Assert.Equal(carCount - 1, newCarCount);Assert.Equal(EntityState.Detached,Context.Entry(car).State);}}Перехват отказов каскадного удаления
Когда попытка удаления записи терпит неудачу из-за правил каскадирования, то исполняющая среда EFCore генерирует исключение
. Следующий тест демонстрирует это в действии:DbUpdateException[Fact]public void ShouldFailToRemoveACar(){ExecuteInATransaction(RunTheTest);void RunTheTest()