现在我想做两件事:
首先进行一次数据库调用,并获取整个分支列表的完整对象(ID、代码、值)。
之后,我将更改每个对象的“值”。
然后我想进行一次数据库调用,并为每行保存更新的“值”。
第二部分很简单-只需移动
SaveChanges()
在循环外部调用。
第一部分很棘手。在撰写本文时(EF Core 2.0.2),
Contains
只能与单个属性一起使用,并连接到内存中的集合,
Concat
基于查询或类似筛选器
.Where(e => listOfBranch.Any(b => b.ID == e.ID && b.Code == e.Code))
所有这些都不会转换为SQL,而是在本地进行计算。
使用单个数据库查询获得所需结果的唯一方法是动态构建如下筛选条件:
.Where(e =>
(e.ID == listOfBranch[0].ID && e.Code == listOfBranch[0].Code)
||
(e.ID == listOfBranch[1].ID && e.Code == listOfBranch[1].Code)
// ...
||
(e.ID == listOfBranch[N-1].ID && e.Code == listOfBranch[N-1].Code)
)
您可以使用
Expression
按如下方式对方法进行分类(只需替换
Record
实体类型):
var parameter = Expression.Parameter(typeof(Record));
var body = listOfBranch
.Select(b => Expression.AndAlso(
Expression.Equal(Expression.Property(parameter, "ID"), Expression.Constant(b.ID)),
Expression.Equal(Expression.Property(parameter, "Code"), Expression.Constant(b.Code))))
.Aggregate(Expression.OrElse);
var predicate = Expression.Lambda<Func<Record, bool>>(body, parameter);
以及用法:
foreach (var record in context.Table.Where(predicate))
{
record.Value = "new value";
}
context.SaveChanges();