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


91

表:

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状态的查询为true。[一次2,3,4]。

谢谢

Answers:


234

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

选项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();
}

更新资料

根据注释中的要求,可能有必要显示如何更新多个列。因此,就本练习而言,我们不仅仅希望更新statusat。我们要更新name,并statusfriendid为匹配。这是一些语法选项:

选项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()

6
对于多个评论,您需要执行以下操作:records.ForEach(x=> { x.Deleted = true; x.DeletedByUserID = deletedByUserId; x.DeletedOn = DateTime.Now; });
JonH

2
应该db.SaveChanges()不是db.SubmitChanges()吗?
bradlis7 2014年

3
...您的所有三个选项都相同。实际上,前两者之间的唯一区别是,一个使用变量,一个不使用变量。两者都只是增加了噪音。
BlueRaja-Danny Pflughoeft 2015年

3
有没有可能做ToList()?这是杀手
工具包

2
ToList()是否根据条件从数据库获取所有记录,不是吗?如果正确的话,那将是非常糟糕的性能。如果有数百万条记录,我们将它们加载到内存中以运行此功能怎么办?如果我弄错了,请纠正我。
雅各布

20

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

运行SQL事件探查器,我验证并发现该ToList()函数从数据库中获取所有记录。真的是糟糕的表现!

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

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

这样就可以一次性完成更新,而无需选择任何一行。


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

希望可以帮助某人。


奇迹般有效!
洋剑

4
这是不好的,每次你调用数据库来获取该记录feature,也不要添加context.SaveChanges()里面foreach应该是外面的foreach循环。
Jawand Singh's

1
SQL与EF代码不同。在SQL中,只有1条命令可在所有行上运行并更新表。EF代码首先获取所有行,然后更新数据库上已更改的行,这意味着如果您有1000条更新的行,它将执行1000条sql更新
Ashkan Sirous

1
@stom还是不一样:) context.SaveChanges(); 只需提交您的更新。仍然会有1000个更新命令,每个更新命令都使用id而不是SortOrder条件
Ashkan

2
为此,在EF上存在@stom ExecuteSqlCommand,但我同意它并不漂亮:)无论如何,我的意思是,您编写了一条SQL命令和一个不同的EF-C#代码,并声称它们相等。:)
Ashkan Sirous
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.