Làm thế nào để cập nhật nhiều hàng cùng một lúc bằng cách sử dụng linq để sql?


91

Bàn:

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

nếu người dùng gửi userid = 1, friendids = 2,4,5 status = true

vui lòng cho tôi biết câu hỏi về cách cập nhật trạng thái friendids ở trên là đúng. [2,3,4 cùng một lúc].?

cảm ơn

Câu trả lời:


234

Để cập nhật một cột, đây là một số tùy chọn cú pháp:

lựa chọn 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();
}

Lựa chọn 2

using (var db=new SomeDatabaseContext())
{
     db.SomeTable
       .Where(x=>ls.Contains(x.friendid))
       .ToList()
       .ForEach(a=>a.status=true);

     db.SubmitChanges();
}

Lựa chọn 3

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

Cập nhật

Theo yêu cầu trong nhận xét, có thể có ý nghĩa khi hiển thị cách cập nhật nhiều cột. Vì vậy, giả sử vì mục đích của bài tập này rằng chúng tôi không chỉ muốn cập nhật statusnhững cái mới nhất. Chúng tôi muốn cập nhật namestatusvị trí friendidphù hợp. Dưới đây là một số tùy chọn cú pháp cho điều đó:

lựa chọn 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();
}

Lựa chọn 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();
}

Lựa chọn 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();
}

Cập nhật 2

Trong câu trả lời, tôi đã sử dụng LINQ to SQL và trong trường hợp đó để cam kết với cơ sở dữ liệu, cách sử dụng là:

db.SubmitChanges();

Nhưng để Entity Framework thực hiện các thay đổi thì đó là:

db.SaveChanges()

6
Và để có nhiều nhận xét, bạn cần thực hiện:records.ForEach(x=> { x.Deleted = true; x.DeletedByUserID = deletedByUserId; x.DeletedOn = DateTime.Now; });
JonH

2
Không nên db.SaveChanges()và không nên db.SubmitChanges()?
bradlis 7

3
... Cả ba tùy chọn của bạn đều giống nhau. Trên thực tế, sự khác biệt duy nhất giữa hai biến đầu tiên là một biến sử dụng một biến và một biến thì không. Có cả hai chỉ là tăng tiếng ồn.
BlueRaja - Danny Pflughoeft

3
là nó có thể làm mà không có ToList()? Đó là một kẻ giết người
Bộ công cụ

2
ToList () có lấy tất cả các bản ghi từ cơ sở dữ liệu, theo điều kiện, phải không? Nếu đúng, nó sẽ là một hiệu suất thực sự tồi tệ, Điều gì sẽ xảy ra nếu có hàng triệu bản ghi, chúng ta tải chúng vào bộ nhớ để vận hành chức năng này? Vui lòng sửa cho tôi nếu tôi nhầm lẫn.
Jacob

20

Không sử dụng ToList()phương pháp như trong câu trả lời được chấp nhận!

Đang chạy trình biên dịch SQL, tôi đã xác minh và thấy rằng ToList()hàm lấy tất cả các bản ghi từ cơ sở dữ liệu. Đó là hiệu suất thực sự tồi tệ !!

Tôi sẽ chạy truy vấn này bằng lệnh sql thuần túy như sau:

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

Thao tác này sẽ vận hành cập nhật trong một lần mà không cần chọn dù chỉ một hàng.


3

Đây là những gì tôi đã làm:

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

Hy vọng sẽ giúp ai đó.


Hoạt động như một sự quyến rũ!
Yu Yang Jian

4
điều này thật tệ, bạn đang gọi cơ sở dữ liệu mỗi lần để tìm nạp bản ghi featurevà bạn cũng không nên thêm context.SaveChanges()vào bên trong foreachnó nên nằm ngoài vòng lặp foreach.
Jawand Singh

1
SQL không giống với mã EF. Trong SQL nó chỉ là 1 lệnh chạy trên tất cả các hàng và cập nhật bảng. Mã EF mất tất cả các hàng đầu tiên, cập nhật những thay đổi trên DB, có nghĩa là nếu bạn có 1000 dòng cập nhật, nó sẽ thực hiện năm 1000 cập nhật sql
Ashkan Sirous

1
@stom Nó vẫn không giống nhau :) context.SaveChanges (); chỉ cần gửi bản cập nhật của bạn. vẫn sẽ được 1000 lệnh cập nhật mỗi sử dụng id và không phải là điều kiện SortOrder
Ashkan Sirous

2
@stom ExecuteSqlCommand tồn tại trên EF cho mục đích này nhưng tôi đồng ý rằng nó không đẹp :) Dù sao, quan điểm của tôi là bạn đã viết một lệnh SQL và một mã EF-C # khác nhau và tuyên bố rằng chúng ngang nhau. :)
Ashkan Sirous
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.