.NET Разработчик
6.52K subscribers
442 photos
3 videos
14 files
2.12K links
Дневник сертифицированного .NET разработчика. Заметки, советы, новости из мира .NET и C#.

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
Какого асинхронного метода НЕ существует в Entity Framework Core?
#Quiz #EFCore
Anonymous Quiz
13%
CountAsync
4%
ToListAsync
7%
SingleAsync
30%
OrderByAsync
13%
MaxAsync
32%
ForEachAsync
👍40👎16
День 2021. #ЗаметкиНаПолях #EFCore
Полезные Функции EF Core. Начало
EF Core – мощный инструмент, и знание нескольких ключевых функций может сэкономить вам много времени и избежать разочарований.

1. Разделение запросов
Функция которая нужна редко, но, когда требуется, приходится очень кстати. Разделение запросов полезно в сценариях, где вы ждёте загрузки из нескольких коллекций. Она помогает избежать проблемы декартового взрыва.

Допустим, вы хотите получить отдел со всеми командами, сотрудниками и их задачами:
List<Department> departments =
context.Departments
.Include(d => d.Teams)
.ThenInclude(t => t.Employees)
.ThenInclude(e => e.Tasks)
.ToList();

Это преобразуется в один SQL-запрос с несколькими JOIN. Предположим, что в отделе много команд, а в каждой команде много сотрудников. В этом случае БД возвращает много строк из каждого подзапроса, что значительно влияет на производительность. Вот как можно избежать этих проблем с производительностью с помощью разделения запросов:
List<Department> departments =
context.Departments
.Include(d => d.Teams)
.ThenInclude(t => t.Employees)
.ThenInclude(e => e.Tasks)
.AsSplitQuery()
.ToList();

При использовании AsSplitQuery EF Core будет выполнять дополнительный SQL-запрос для каждого навигационного свойства коллекции. Однако не злоупотребляйте разделением запросов. Измерьте производительность в каждом случае для вашего конкретного набора данных. Разделённые запросы делают больше обращений к БД, что может быть медленнее, если задержка базы данных высока. Также нет гарантии согласованности между несколькими SQL-запросами.

См. подробнее о разделённых запросах.

2. Массовые обновления и удаления
EF Core 7 добавил два новых API для выполнения массовых обновлений и удалений, ExecuteUpdate и ExecuteDelete. Они позволяют эффективно обновлять большое количество строк за один цикл обращения к БД.

Например, компания решила повысить зарплату на 5% всем сотрудникам в отделе «Продажи». Мы могли бы пройтись по всем сотрудникам и обновить их зарплату:
var salesEmployees = context.Employees
.Where(e => e.Department == "Sales")
.ToList();

foreach (var employee in salesEmployees)
employee.Salary *= 1.05m;

context.SaveChanges();

Этот подход приведёт к множеству запросов в БД, что может быть неэффективным, особенно для больших наборов данных. Мы можем добиться того же за один запрос, используя ExecuteUpdate:
context.Employees
.Where(e => e.Department == "Sales")
.ExecuteUpdate(s =>
s.SetProperty(e => e.Salary, e => e.Salary * 1.05m));

Это приведёт к одному SQL-запросу UPDATE, и прямому изменению зарплаты в БД без загрузки сущностей в память.

Ещё пример. Допустим, платформа электронной коммерции хочет удалить все корзины покупок старше года:
context.Carts
.Where(o => o.CreatedOn < DateTime.Now.AddYears(-1))
.ExecuteDelete();

Однако массовые обновления обходят трекер изменений EF. Это может быть проблемой, о чём см. подробнее.

Окончание следует…

Источник:
https://www.milanjovanovic.tech/blog/5-ef-core-features-you-need-to-know
👍35
День 2022. #ЗаметкиНаПолях #EFCore
Полезные Функции EF Core. Окончание

Начало

3. Чистые SQL-запросы
EF Core 8 добавил новую функцию, которая позволяет нам запрашивать несопоставленные (unmapped) типы. Предположим, мы хотим получить данные из представления БД, хранимой процедуры или таблицы, которые напрямую не соответствуют ни одному из классов сущностей контекста БД. Например, получить сводные данные продаж продукта. В EF Core 8 можно определить простой класс и запросить его напрямую:
public class ProductSummary
{
public int Id { get; set; }
public string Name { get; set; }
public decimal TotalSales { get; set; }
}

var sums = await context.Database
.SqlQuery<ProductSummary>(
@$"""
SELECT p.Id, p.Name,
SUM(oi.Quantity * oi.UnitPrice) AS TotalSales
FROM Products p
JOIN OrderItems oi ON p.ProductId = oi.ProductId
WHERE p.CategoryId = {categoryId}
GROUP BY p.Id, p.Name
""")
.ToListAsync();

Метод SqlQuery возвращает IQueryable, что позволяет встраивать чистые SQL-запросы в LINQ-запросы.

Не забывайте использовать параметризованные запросы, чтобы предотвратить SQL-инъекции. Метод SqlQuery принимает FormattableString, что означает, что вы можете безопасно использовать интерполированную строку. Каждый аргумент преобразуется в параметр SQL.

См. подробнее.

4. Фильтры запросов
Фильтры автоматически добавляются в LINQ-запросы, когда вы извлекаете сущности соответствующего типа. Это избавляет от необходимости многократно писать одну и ту же логику фильтрации в нескольких местах.

Обычные сценарии:
- Мягкие удаления: отфильтровывают записи, помеченные как удалённые.
- Мультитенантность: фильтруют данные на основе текущего пользователя.
- Безопасность на уровне строк: ограничивают доступ к определённым записям на основе ролей или разрешений пользователей.

В мультитенантном приложении часто нужно фильтровать данные на основе текущего пользователя:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
// Связываем продукты с пользователями
public int TenantId { get; set; }
}

protected override void
OnModelCreating(ModelBuilder mb)
{
// Текущий пользователь задаётся из контекста/запроса
mb.Entity<Product>()
.HasQueryFilter(p => p.TenantId == _currentTenantId);
}

// Запросы автоматически фильтруются по пользователю:
var products = context.Products.ToList();

См. подробнее о мультитенантности с помощью EF Core.

Настройка нескольких фильтров запроса для одной сущности применит только последний. Можно использовать IgnoreQueryFilters, чтобы обойти фильтры в запросах, где это необходимо.

Источник: https://www.milanjovanovic.tech/blog/5-ef-core-features-you-need-to-know
👍26