[ef+](https://entityframework-plus.net/ef-core-batch-delete)
# 批量删除
## 描述
如果需要删除数百或数千个实体,使用实体框架核心删除可能会非常缓慢。实体在删除之前先在上下文中加载,这对性能非常不利,然后逐个删除,这使得删除操作更加糟糕。
>EF® 批处理删除删除单个数据库往返中的多行,并且在上下文中不加载实体
## 代码示例
```C#
// DELETE all users inactive for 2 years
var date = DateTime.Now.AddYears(-2);
ctx.Users.Where(x => x.LastLoginDate < date)
.Delete();
// DELETE using a BatchSize
var date = DateTime.Now.AddYears(-2);
ctx.Users.Where(x => x.LastLoginDate < date)
.Delete(x => x.BatchSize = 1000);
```
# 批量更新
```C#
// UPDATE all users inactive for 2 years
var date = DateTime.Now.AddYears(-2);
ctx.Users.Where(x => x.LastLoginDate < date)
.Update(x => new User() { IsSoftDeleted = 1 });
```
# 查询缓存
## 描述
缓存实体或查询结果以提高应用程序的性能是一种非常常见的方案。像 NHibernate 这样的主要 ORM 具有很长一段时间的此功能,但不幸的是,对于实体框架核心用户来说,第二级缓存只能通过第三方库获得。
缓存非常简单,在首次调用查询时,将从数据库中检索数据,并在返回之前存储在内存中。所有将来的调用都将从内存中检索数据,以避免进行额外的数据库往返,从而显著提高应用程序的性能。
`EF+ 查询缓存`为实体框架核心用户打开所有缓存功能。
要使用缓存,只需追加到查询"FromCache"方法,然后使用即时解析方法(如"Tolist()"或"FirstOrdefault()")。
```C#
// using Z.EntityFramework.Plus; // Don't forget to include this.
var ctx = new EntitiesContext();
// The first call perform a database round trip
var countries1 = ctx.Countries.FromCache().ToList();
// Subsequent calls will take the value from the memory instead
var countries2 = ctx.Countries.FromCache().ToList();
```
# 查询筛选器
```C#
QueryFilterManager.Filter
(q => q.Where(x => !x.IsSoftDeleted));
var ctx = new EntitiesContext();
// SELECT * FROM Post WHERE IsSoftDeleted = false
var list = ctx.Posts.ToList();
```
# 查询延迟
```C#
// CREATE a pending list of future queries
var futureCountries = db.Countries.Where(x => x.IsActive).Future();
var futureStates = db.States.Where(x => x.IsActive).Future();
// TRIGGER all pending queries in one database round trip
// SELECT * FROM Country WHERE IsActive = true;
// SELECT * FROM State WHERE IsActive = true
var countries = futureCountries.ToList();
// futureStates is already resolved and contains the result
var states = futureStates.ToList();
```
# 查询包括优化
## 描述
实体框架在生成查询方面做了出色的工作,但是,它们并不总是经过优化,最终传输的数据可能比查询真正需要的数据多。
EF+ 包含优化生成的 SQL 执行多个 SELECT,但会大大减少传输的数据量。
## 实体框架生成的 SQL
```C#
var orders = ctx.Orders
.Where(x => x.OrderId == myOrderID) // 1 orders, 20 columns
.Include(x => x.Items) // 20 items, 10 columns
.Include(x => x.DeliveredItems) // 10 items, 10 columns
.ToList();
// return 20 + 10 = 30 rows
// return 20 + 10 + 10 = 40 columns
// total: 30 rows * 40 columns = 1200 cells transferred
```
在某些查询中,仅传输一次标头信息 30 倍可能看起来微不足道,但随着项数和"包括"方法的增加,它可能成为一个重大开销,在许多情况下可能成为关键的性能问题,甚至会导致 SQL 超时。
## EF+ 生成的 SQL 包括优化
```C#
// SELECT * FROM Order WHERE....
// SELECT * FROM OrderItem WHERE EXISTS (/* previous query */) AND ...
// SELECT * FROM DeliveryItems WHERE EXISTS (/* previous query */) AND ...
var orders = ctx.Orders
.Where(x => x.OrderId == myOrderID) // 1 orders, 20 columns
.IncludeOptimized(x => x.Items) // 20 items, 10 columns
.IncludeOptimized(x => x.DeliveredItems) // 10 items, 10 columns
.ToList();
// return 1 row * 20 columns = 20 cells
// return 20 rows * 10 columns = 200 cells
// return 10 rows * 10 columns = 100 cells
// total: 20 + 200 + 100 = 320 cells transferred
```
## EF+ 查询包括优化
IncludeOptimized 方法的工作方式类似于"包括"方法,但会创建一个有效的查询来减少要传输的数据数。
```C#
// using Z.EntityFramework.Plus; // Don't forget to include this.
var ctx = new EntitiesContext();
var orders = ctx.Orders.IncludeOptimized(x => x.Items);
```
没有帐号?立即注册