Шрифт:
Интервал:
Закладка:
Context.Makes.Add(make);
var carCount = Context.Cars.Count();
var makeCount = Context.Makes.Count();
Context.SaveChanges();
var newCarCount = Context.Cars. Count();
var newMakeCount = Context.Makes. Count();
Assert.Equal(carCount+1,newCarCount);
Assert.Equal(makeCount+1,newMakeCount);
}
}
Операторы добавления не пакетируются из-за наличия менее двух операторов, а в SQL Server пакетирование начинается с четырех операторов. Ниже показаны выполняемые операторы SQL:
exec sp_executesql N'SET NOCOUNT ON;
INSERT INTO [dbo].[Makes] ([Name])
VALUES (@p0);
SELECT [Id], [TimeStamp]
FROM [dbo].[Makes]
WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity();
',N'@p0 nvarchar(50)',@p0=N'Honda'
exec sp_executesql N'SET NOCOUNT ON;
INSERT INTO [dbo].[Inventory] ([Color], [MakeId], [PetName])
VALUES (@p1, @p2, @p3);
SELECT [Id], [IsDrivable], [TimeStamp]
FROM [dbo].[Inventory]
WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity();
',N'@p1 nvarchar(50),@p2 int,@p3 nvarchar(50)',@p1=N'Yellow',@p2=7,@p3=N'Herbie'
Обновление записей
Записи обновляются за счет их загрузки в DbSet<T> как отслеживаемой сущности, их изменения посредством кода и вызова метода SaveChanges() контекста. При выполнении SaveChanges() объект ChangeTracker сообщает обо всех модифицированных сущностях и исполняющая среда EF Core (наряду с поставщиком баз данных) создает надлежащий оператор SQL для обновления записи (или операторы SQL, если записей несколько).
Состояние сущности
Когда сущность редактируется, EntityState устанавливается в Modified. После успешного сохранения изменений состояние возвращается к Unchanged.
Обновление отслеживаемых сущностей
Обновление одиночной записи очень похоже на добавление одной записи. Вам понадобится загрузить запись из базы данных, внести в нее какие-то изменения и вызвать метод SaveChanges(). Обратите внимание, что вам не нужно вызывать Update()/UpdateRange() на экземпляре DbSet<T>, поскольку сущности отслеживаются. Представленный ниже тест обновляет только одну запись, но при обновлении и сохранении множества отслеживаемых сущностей процесс будет таким же:
[Fact]
public void ShouldUpdateACar()
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390}){
ExecuteInASharedTransaction(RunTheTest);
void RunTheTest(IDbContextTransaction trans)
{
var car = Context.Cars.First(c => c.Id == 1);
Assert.Equal("Black",car.Color);
car.Color = "White";
// Вызывать Update() не нужно, т.к. сущность отслеживается.
// Context.Cars.Update(car);
Context.SaveChanges();
Assert.Equal("White", car.Color);
var context2 = TestHelpers.GetSecondContext(Context, trans);
var car2 = context2.Cars.First(c => c.Id == 1);
Assert.Equal("White", car2.Color);
}
}
В предыдущем коде задействована транзакция, совместно используемая двумя экземплярами ApplicationDbContext. Это должно обеспечить изоляцию между контекстом, выполняющим тест, и контекстом, проверяющим результат теста. Вот выполняемый оператор SQL:
exec sp_executesql N'SET NOCOUNT ON;
UPDATE [dbo].[Inventory] SET [Color] = @p0
WHERE [Id] = @p1 AND [TimeStamp] = @p2;
SELECT [TimeStamp]
FROM [dbo].[Inventory]
WHERE @@ROWCOUNT = 1 AND [Id] = @p1;
',N'@p1 int,@p0 nvarchar(50),@p2 varbinary(8)',@p1=1,@p0=N'White',
@p2=0x000000000000862D
На заметку! В показанной выше конструкции WHERE проверяется не только столбец Id, но и столбец TimeStamp. Проверка параллелизма будет раскрыта очень скоро .
Обновление неотслеживаемых сущностей
Неотслеживаемые сущности тоже можно использовать для обновления записей базы данных. Процесс аналогичен обновлению отслеживаемых сущностей за исключением того, что сущность создается в коде (и не запрашивается), а исполняющую среду EF Core потребуется уведомить о том, что сущность уже должна существовать в базе данных и нуждается в обновлении.
После создания экземпляра сущности есть два способа уведомления EF Core о том, что эту сущность необходимо обработать как обновление. Первый способ предусматривает вызов метода Update() на экземпляре DbSet<T>, который устанавливает состояние в Modified:
context2.Cars.Update(updatedCar);
Второй способ связан с применением экземпляра контекста и метода Entry() для установки состояния в Modified:
- Понимание SQL - Мартин Грубер - Базы данных