return (string)parameterName.Value;
}
При наличии такого кода тест становится тривиальным. Добавьте в файл класса CarTests.cs
следующий тест:
[Theory]
[InlineData(1, "Zippy")]
[InlineData(2, "Rusty")]
[InlineData(3, "Mel")]
[InlineData(4, "Clunker")]
[InlineData(5, "Bimmer")]
[InlineData(6, "Hank")]
[InlineData(7, "Pinky")]
[InlineData(8, "Pete")]
[InlineData(9, "Brownie")]
public void ShouldGetValueFromStoredProc(int id, string expectedName)
{
Assert.Equal(expectedName, new CarRepo(Context).GetPetName(id));
}
Создание записей
Записи добавляются в базу данных за счет их создания в коде, добавления к DbSet
и вызова метода SaveChanges()/SaveChangesAsync()
контекста. Во время выполнения метода SaveChanges()
объект ChangeTracker
сообщает обо всех добавленных сущностях, а инфраструктура EF Core вместе с поставщиком баз данных создают подходящий оператор (операторы) SQL для вставки записи (записей).
Вспомните, что метод SaveChanges()
выполняется в неявной транзакции, если только не применяется явная транзакция. Если сохранение было успешным, то затем запрашиваются значения, сгенерированные сервером, для установки значений в сущностях. Все эти тесты будут использовать явную транзакцию, так что можно производить откат, оставив базу данных в том же состоянии, в каком она находилась, когда начинался прогон тестов.
Все операторы SQL, показанные далее в разделе, были получены с применением профилировщика SQL Server.
На заметку! Записи можно добавлять также с использованием класса, производного от DbContext
. Во всех примерах для добавления записей будут применяться свойства DbSet
. В классах DbSet
и DbContext
имеются асинхронные версии методов Add()/AddRange()
, но здесь рассматриваются только синхронные версии.
Состояние сущности
Когда сущность создана с помощью кода, но еще не была добавлена в DbSet
, значением EntityState
является Detached
. После добавления новой сущности в DbSet
значение EntityState
устанавливается в Added
. В случае успешного выполнения SaveChanges()
значение EntityState
устанавливается в Unchanged
.
Добавление одной записи
В следующем тесте демонстрируется добавление одиночной записи в таблицу Inventory
:
[Fact]
public void ShouldAddACar()
{
ExecuteInATransaction(RunTheTest);
void RunTheTest()
{
var car = new Car
{
Color = "Yellow",
MakeId = 1,
PetName = "Herbie"
};
var carCount = Context.Cars.Count();
Context.Cars.Add(car);
Context.SaveChanges();
var newCarCount = Context.Cars.Count();
Assert.Equal(carCount+1,newCarCount);
}
}
Ниже приведен выполняемый оператор SQL. Обратите внимание, что у недавно добавленной сущности запрашиваются свойства, сгенерированные базой данных (Id
и TimeStamp
). Когда результат запроса поступает в исполняющую среду EF Core, сущность обновляется с использованием значений серверной стороны:
exec sp_executesql N'SET NOCOUNT ON;
INSERT INTO [dbo].[Inventory] ([Color], [MakeId], [PetName])
VALUES (@p0, @p1, @p2);
SELECT [Id], [IsDrivable], [TimeStamp]
FROM [dbo].[Inventory]
WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity();
',N'@p0 nvarchar(50),@p1 int,@p2 nvarchar(50)',@p0=N'Yellow',@p1=1,@p2=N'Herbie'
Добавление одной записи с использованием метода Attach()
Когда первичный ключ сущности сопоставлен со столбцом идентичности в SQL Server, исполняющая среда EF Core будет трактовать экземпляр сущности как добавленный (Added
), если значение свойства первичного ключа равно 0. Следующий тест создает новую сущность Car
и оставляет для свойства Id
стандартное значение 0. После присоединения сущности к ChangeTracker
ее состояние устанавливается в Added
и вызов SaveChanges()
добавит сущность в базу данных:
[Fact]
public void ShouldAddACarWithAttach()
{