从 id 列表中更新实体框架中的多行

我正在尝试创建一个实体框架查询,它允许我获取 id 列表并更新与之相关的字段。

SQL 中的示例:

UPDATE Friends
SET msgSentBy = '1234'
WHERE id IN (1, 2, 3, 4)

如何将上述内容转换为实体框架?

188989 次浏览

比如下面

var idList=new int[]{1, 2, 3, 4};
using (var db=new SomeDatabaseContext())
{
var friends= db.Friends.Where(f=>idList.Contains(f.ID)).ToList();
friends.ForEach(a=>a.msgSentBy='1234');
db.SaveChanges();
}

更新:

您可以如下所示更新多个字段

friends.ForEach(a =>
{
a.property1 = value1;
a.property2 = value2;
});
var idList=new int[]{1, 2, 3, 4};
var friendsToUpdate = await Context.Friends.Where(f =>
idList.Contains(f.Id).ToListAsync();


foreach(var item in previousEReceipts)
{
item.msgSentBy = "1234";
}

可以使用 foreach 更新满足条件的每个元素。

下面是一个比较通用的例子:

var itemsToUpdate = await Context.friends.Where(f => f.Id == <someCondition>).ToListAsync();


foreach(var item in itemsToUpdate)
{
item.property = updatedValue;
}
Context.SaveChanges()

一般来说,在等待数据库查询时最有可能使用异步方法。

我已经创建了一个库批量删除或更新记录与 EFCore5的往返旅行。

样本代码如下:

await ctx.DeleteRangeAsync(b => b.Price > n || b.AuthorName == "zack yang");


await ctx.BatchUpdate()
.Set(b => b.Price, b => b.Price + 3)
.Set(b=>b.AuthorName,b=>b.Title.Substring(3,2)+b.AuthorName.ToUpper())
.Set(b => b.PubTime, b => DateTime.Now)
.Where(b => b.Id > n || b.AuthorName.StartsWith("Zack"))
.ExecuteAsync();

Github 存储库: < a href = “ https://Github.com/yangzhongke/Zack.EFCore.Batch”rel = “ nofollow norefrer”> https://Github.com/yangzhongke/zack.efcore 报告: < a href = “ https://www.reddit.com/r/dotnetcore/comments/k1esra/how _ to _ batch _ delete _ or _ update _ in _ tity _ Framework/”rel = “ nofollow norefrer”> https://www.reddit.com/r/dotnetcore/comments/k1esra/how_to_batch_delete_or_update_in_entity_framework/

实体框架核心5.0中引入的 IQueryable.ToQueryString方法可能对此场景有所帮助,如果您愿意在代码中显示一些原始 SQL 的话。此方法将生成可包含在原始 SQL 查询中的 SQL,以执行该查询标识的记录的批量更新。

例如:

using var context = new DbContext();


var ids = new List<int>() { 1, 2, 3, 4 };


var query = context.Friends.Where(_ => ids.Contains(_.id)).Select(_ => _.id);


var sql = $"UPDATE Friends SET msgSentBy = \{\{0}} WHERE id IN ({query.ToQueryString()})";


context.Database.ExecuteSqlRaw(sql, "1234");

这种方法的主要缺点是使用原始 SQL。然而,我不知道有什么合理的方法可以避免目前的实体框架核心功能-你被困在这个警告,或其他的警告的答案张贴在这里,如:

如果(当)以下问题在未来得到解决,那么我们很可能在这里得到一个更好的答案: 批量(即基于集的) CUD 操作(不将数据加载到内存中) # 795