批量操作
1、Batch 方法
Batch 方法可以将一个序列的实体一次性进行插入、更新或删除。在批量操作之前,先构造一个实体集。
[TestMethod]
public void TestBatchInsert()
{
using (var db = new DbContext())
{
var list = new List<Products>();
for (var i = 0; i < 10; i++)
{
var product = db.New<Products>();
product.ProductName = "aa" + i;
product.Discontinued = 0;
list.Add(product);
}
db.Products.Batch(list, (u, s) => u.Insert(s));
}
}
Batch 方法的 lambda
表达式支持 Insert、Update 和 Delete 操作。使用 Update 或 Delete 时,应注意集合里的实体必须给定其主键值,否则将不能完成批量操作。
使用批量操作时应注意,默认尾部下所生成的 SQL
语句是以第一个实体的属性状态做为参照的。如果集合中每个实体的属性可能不相同,则应指定 BatchCheckModifiedKinds.Everyone
。
[TestMethod]
public void TestBatchInsert()
{
using (var db = new DbContext())
{
var list = new List<Products>();
for (var i = 0; i < 10; i++)
{
var product = db.New<Products>();
product.ProductName = "test" + i;
product.Discontinued = 0;
list.Add(product);
}
list[6].QuantityPerUnit = "kg"; //单独设置了某一个实体的某一个属性
var options = new BatchOperateOptions(BatchCheckModifiedKinds.Everyone);
db.Products.Batch(list, (u, s) => u.Insert(s), options);
}
}
你也可以使用 属性过滤 来设置需要插入或更新的属性。BatchOperateOptions
类有一个 PropertyFilter 属性,你可以添加要过滤的属性。如下所示:
[TestMethod]
public void TestBatchInsertWithPropertyFilter()
{
using (var db = new DbContext())
{
var list = new List<Products>();
for (var i = 0; i < 10; i++)
{
var product = db.New<Products>();
product.ProductName = "test" + i;
product.Discontinued = 0;
list.Add(product);
}
list[6].QuantityPerUnit = "kg"; //单独设置了某一个实体的某一个属性
var options = new BatchOperateOptions
{
PropertyFilter = PropertyFilter<Products>.Inclusive()
.With(s => s.ProductName)
.With(s => s.QuantityPerUnit)
};
db.Products.Batch(list, (u, s) => u.Insert(s), options);
}
}
使用批量操作插入的实体,你也可以获取到每一个实体的主键值。
2、UseBatch 扩展方法
EntityContext
的扩展方法 UseBatch 将开启一个批执行范围,在此期间,所有的 Insert、Update 和 Delete 语句将合并为一条指令提交给数据库。这适用于不关注操作返回值但希望提高执行效率的情形下。如下所示:
[TestMethod]
public async Task TestUseBagch()
{
using (var db = new DbContext())
{
await db.UseBatchAsync(async db =>
{
var order = await db.Orders.FirstOrDefaultAsync();
await db.Orders.DeleteAsync(s => s.OrderDate == DateTime.Now && s.OrderID == order.OrderID);
db.Customers.Delete(s => s.CustomerID == "test");
db.Products.Delete(s => s.ProductName == "test");
});
}
}
💡 小提示
UseBatch 方法范围内,Insert、Update 和 Delete 的同步/异步方法是同等的,不必刻意区分。即异步是由 UseBatchAsync 方法所决定的。