如何使用 linq to sql 一次更新多行?

Posted

技术标签:

【中文标题】如何使用 linq to sql 一次更新多行?【英文标题】:how to update the multiple rows at a time using linq to sql? 【发布时间】:2012-04-25 11:19:30 【问题描述】:

表:

id     userid  friendid   name    status
1      1        2         venkat  false
2      1        3         sai     true
3      1        4         arun    false
4      1        5         arjun   false

如果用户发送userid=1,friendids=2,4,5 status=true

我将如何编写查询来更新上述内容?所有friendids 状态均为真。 [一次 2,3,4 个]?

【问题讨论】:

【参考方案1】:

要更新一列,这里有一些语法选项:

选项 1

var ls=new int[]2,3,4;
using (var db=new SomeDatabaseContext())

    var some= db.SomeTable.Where(x=>ls.Contains(x.friendid)).ToList();
    some.ForEach(a=>a.status=true);
    db.SubmitChanges();

选项 2

using (var db=new SomeDatabaseContext())

     db.SomeTable
       .Where(x=>ls.Contains(x.friendid))
       .ToList()
       .ForEach(a=>a.status=true);

     db.SubmitChanges();

选项 3

using (var db=new SomeDatabaseContext())

    foreach (var some in db.SomeTable.Where(x=>ls.Contains(x.friendid)).ToList())
    
        some.status=true;
    
    db.SubmitChanges();

更新

根据评论中的要求,展示如何更新多个列可能是有意义的。因此,假设出于本练习的目的,我们不仅要更新status at 个。我们要更新namestatus 匹配的friendid。以下是一些语法选项:

选项 1

var ls=new int[]2,3,4;
var name="Foo";
using (var db=new SomeDatabaseContext())

    var some= db.SomeTable.Where(x=>ls.Contains(x.friendid)).ToList();
    some.ForEach(a=>
                    
                        a.status=true;
                        a.name=name;
                    
                );
    db.SubmitChanges();

选项 2

using (var db=new SomeDatabaseContext())

    db.SomeTable
        .Where(x=>ls.Contains(x.friendid))
        .ToList()
        .ForEach(a=>
                    
                        a.status=true;
                        a.name=name;
                    
                );
    db.SubmitChanges();

选项 3

using (var db=new SomeDatabaseContext())

    foreach (var some in db.SomeTable.Where(x=>ls.Contains(x.friendid)).ToList())
    
        some.status=true;
        some.name=name;
    
    db.SubmitChanges();

更新 2

在我使用 LINQ to SQL 的答案中,在这种情况下提交到数据库的用法是:

db.SubmitChanges();

但要让实体框架提交更改:

db.SaveChanges()

【讨论】:

对于多个 cmets 你需要做:records.ForEach(x=> x.Deleted = true; x.DeletedByUserID = deletedByUserId; x.DeletedOn = DateTime.Now; ); 不应该是db.SaveChanges()而不是db.SubmitChanges()吗? ...您的所有三个选项都是相同的。事实上,前两者之间的唯一区别是一个使用变量而一个不使用。两者兼有只会增加噪音。 注意:这将生成一个单独的 SQL 更新查询 per 行。在这种情况下它不是,但如果 # 行是“重要的”(即 mil 的、k 的甚至 100 的),您可能希望通过嵌入式 SQL 或存储过程来使用单个 SQL 更新查询。来源:“social.msdn.microsoft.com/Forums/en-US/…” 可以不用ToList()吗?这是一个杀手【参考方案2】:

不要在接受的答案中使用ToList() 方法!

运行 SQL 分析器,我验证并发现 ToList() 函数从数据库中获取所有记录。性能真的很差!!

我会通过纯 sql 命令运行此查询,如下所示:

string query = "Update YourTable Set ... Where ...";    
context.Database.ExecuteSqlCommandAsync(query, new SqlParameter("@ColumnY", value1), new SqlParameter("@ColumnZ", value2));

这将在不选择一行的情况下一次性操作更新。

【讨论】:

虽然我同意你的观点,但这个问题确实特别要求 linq 方式。而且,您实际上不需要使用.ToList()。我相信你可以使用.ForEachAsync() 方法或foreach 没有.ToList() 的常规循环。仍然可能不是很好的表现。但是,如果您非常关心 IMO 的性能,则不应使用 EF。【参考方案3】:

这就是我所做的:

EF:

using (var context = new SomeDBContext())

    foreach (var item in model.ShopItems)  // ShopItems is a posted list with values 
        
        var feature = context.Shop
                             .Where(h => h.ShopID == 123 && h.Type == item.Type).ToList();

        feature.ForEach(a => a.SortOrder = item.SortOrder);
    

    context.SaveChanges();

希望能帮助别人。

注意: 5 年后,正如 cmets 中所说,它不是一个好的选择,因为我正在调用数据库以获取 foreach 中的一些数据。如果你不这样做,那么它可以使用。

【讨论】:

像魅力一样工作! 这很糟糕,你每次都调用数据库来获取记录feature,而且你不应该在foreach中添加context.SaveChanges(),它应该在foreach循环之外。 SQL和EF代码不一样。在 SQL 中,它只是在所有行上运行并更新表的 1 个命令。 EF 代码首先获取所有行,更新 DB 上更改的行,这意味着如果您有 1000 条更新的行,它将执行 1000 条 sql 更新 @stom 还是不一样 :) context.SaveChanges();只需提交您的更新。仍然会有 1000 个更新命令,每个命令都使用 id 而不是 SortOrder 条件 @stom ExecuteSqlCommand 为此存在于 EF 上,但我同意它并不漂亮 :) 无论如何,我的意思是你已经编写了一个 SQL 命令和一个不同的 EF-C# 代码并声称他们是平等的。 :)

以上是关于如何使用 linq to sql 一次更新多行?的主要内容,如果未能解决你的问题,请参考以下文章

Linq-To-Sql ORM 更新一对多

Linq to Sql-我可以构建一个通用的更新操作吗?

LINQ to SQL / LINQ to Collections 性能

使用 LINQ to SQL 时如何处理 SqlException“未找到记录”?

LINQ to SQL 关系不更新集合

如何使用 LINQ to SQL 创建通用数据访问对象 (DAO) CRUD 方法