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

问题描述 投票:0回答:6

我正在尝试为实体框架创建一个查询,该查询将允许我获取 ID 列表并更新与它们关联的字段。

SQL 中的例子:

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

如何将上面的转换成实体框架?

c# sql asp.net-mvc entity-framework sql-update
6个回答
210
投票

如下所示

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;
                      });

5
投票

Entity Framework Core 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。但是,我不知道有什么合理的方法可以用当前的 Entity Framework Core 功能来避免这种情况——你被这个警告或这里发布的其他答案的警告所困,例如:

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


4
投票
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()

一般来说,您很可能会使用带有 await 的异步方法来进行数据库查询。


3
投票

我创建了一个库,用于在 EF Core 5 上通过往返批量删除或更新记录。

示例代码如下:

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 仓库:https://github.com/yangzhongke/Zack.EFCore.Batch 报告:https://www.reddit.com/r/dotnetcore/comments/k1esra/how_to_batch_delete_or_update_in_entity_framework/


0
投票

使用 Entity Framework 7 进行大规模更新的最佳方式是这样的:

var idList = new int[]{1, 2, 3, 4};
context.Friends
       .Where(f => idList.Contains(f.ID))
       .ExecuteUpdate(f => f.SetProperty(x => x.Name, x => $"Updated {x.Name}"));

这样做的好处是它不会检索所有记录。它只是发送一个更新查询。

参考:https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-7.0/whatsnew#executeupdate-and-executedelete-bulk-updates


0
投票

对于那些搜索批量更新的人(比如我):

基于Microsoft EF文档,在Performance section (Efficient Update)中,如果要进行批量更新,最好使用执行原始SQL来提高性能。

context.Database.ExecuteSqlRaw("UPDATE [Employees] SET [Salary] = [Salary] + 1000");

https://learn.microsoft.com/en-us/ef/core/performance/efficient-updating

© www.soinside.com 2019 - 2024. All rights reserved.