Язык программирования C#9 и платформа .NET5
Часть 468 из 642 Информация о книге
var car = Context.Cars<b> .FromSqlInterpolated($"Select * from dbo.Inventory where Id = {carId}")</b><b> .Include(x => x.MakeNavigation)</b><b> .First();</b>Assert.Equal("Black", car.Color);Assert.Equal("VW", car.MakeNavigation.Name);}[Theory][InlineData(1, 1)][InlineData(2, 1)][InlineData(3, 1)][InlineData(4, 2)][InlineData(5, 3)][InlineData(6, 1)]public void ShouldGetTheCarsByMakeUsingFromSql(int makeId, int expectedCount){var entity = Context.Model.FindEntityType($"{typeof(Car).FullName}");var tableName = entity.GetTableName();var schemaName = entity.GetSchema();<b> var cars = Context.Cars.FromSqlRaw($"Select * from {schemaName}.{tableName}")</b><b> .Where(x => x.MakeId == makeId).ToList();</b>Assert.Equal(expectedCount, cars.Count);}Во время применения методов
действует ряд правил: столбцы, возвращаемые из оператора SQL, должны соответствовать столбцам в модели, должны возвращаться все столбцы для модели, а возвращать связанные данные не допускается.FromSqlRaw()/FromSqlInterpolated()Методы агрегирования
В EF Core также поддерживаются методы агрегирования серверной стороны (
,Мах(),Min(),Count()и т.д.). Вызовы методов агрегирования можно добавлять в конец запроса LINQ с вызовамиAverage()или же сам вызов метода агрегирования может содержать выражение фильтра (подобноWhere()иFirst()). Агрегирование выполняется на серверной стороне и из запроса возвращается одиночное значение. Глобальные фильтры запросов оказывают воздействие на методы агрегирования и могут быть отключены с помощьюSingle(). В операторы SQL, показанные в этом разделе, были получены с использованием профилировщика SQL Server.IgnoreQueryFiltersсе()Первый тест (из
) просто подсчитывает все записиCarTests.csв базе данных. Из-за того, что фильтр запросов активен, результатом подсчета будет 9:Car[Fact]public void ShouldGetTheCountOfCars(){var count = Context.Cars.Count();Assert.Equal(9, count);}Ниже приведен код SQL, который выполнялся:
The executed SQL is shown here:SELECT COUNT(*)FROM [dbo].[Inventory] AS [i]WHERE [i].[IsDrivable] = CAST(1 AS bit)После добавления вызова
методIgnoreQueryFilters()возвращает 10 и конструкцияCount()удаляется из запроса SQL:WHERE[Fact]public void ShouldGetTheCountOfCarsIgnoreQueryFilters(){var count = Context.Cars.IgnoreQueryFilters().Count();Assert.Equal(10, count);}Вот сгенерированный код SQL:
SELECT COUNT(*) FROM [dbo].[Inventory] AS [i]Следующие тесты (из
) демонстрируют методCarTests.csс условиемCount(). В первом тесте выражение добавляется прямо в вызов методаWHERE, а во втором вызов методаCount()помещается в конец запроса LINQ:Count()[Theory][InlineData(1, 1)][InlineData(2, 1)][InlineData(3, 1)][InlineData(4, 2)][InlineData(5, 3)][InlineData(6, 1)]public void ShouldGetTheCountOfCarsByMakeP1(int makeId, int expectedCount){var count = Context.Cars.Count(x=>x.MakeId == makeId);Assert.Equal(expectedCount, count);}[Theory][InlineData(1, 1)][InlineData(2, 1)][InlineData(3, 1)][InlineData(4, 2)][InlineData(5, 3)][InlineData(6, 1)]public void ShouldGetTheCountOfCarsByMakeP2(int makeId, int expectedCount){var count = Context.Cars.Where(x => x.MakeId == makeId).Count();Assert.Equal(expectedCount, count);}Оба теста создают те же самые обращения SQL к серверу (в каждом тесте значение для
изменяется на основеMakeId):[InlineData]