bagaimana cara memperbarui beberapa baris sekaligus menggunakan LINQ ke Sql?

94

Meja:

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

jika pengguna mengirimkan userid = 1, friendids = 2,4,5 status = true

tolong beri tahu saya pertanyaan tentang cara memperbarui semua status friendids di atas adalah benar. [2,3,4 sekaligus].?

Terima kasih

pengguna1237131
sumber

Jawaban:

238

Untuk memperbarui satu kolom, berikut adalah beberapa opsi sintaks:

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

pilihan 2

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

     db.SubmitChanges();
}

Pilihan 3

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

Memperbarui

Seperti yang diminta dalam komentar, mungkin masuk akal untuk menunjukkan cara memperbarui beberapa kolom. Jadi katakanlah untuk tujuan latihan ini bahwa kita ingin tidak hanya memperbarui statusat ones. Kami ingin memperbarui namedan statusmana yang friendidcocok. Berikut beberapa opsi sintaks untuk itu:

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

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

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

Perbarui 2

Dalam jawaban saya menggunakan LINQ ke SQL dan dalam hal ini untuk berkomitmen ke database, penggunaannya adalah:

db.SubmitChanges();

Tetapi untuk Entity Framework untuk melakukan perubahan itu adalah:

db.SaveChanges()
Arion
sumber
6
Dan untuk beberapa komentar yang perlu Anda lakukan:records.ForEach(x=> { x.Deleted = true; x.DeletedByUserID = deletedByUserId; x.DeletedOn = DateTime.Now; });
JonH
2
Bukankah seharusnya db.SaveChanges()dan tidak db.SubmitChanges()?
bradlis7
3
... Ketiga opsi Anda sama. Faktanya, satu-satunya perbedaan antara dua yang pertama adalah yang satu menggunakan variabel dan yang lainnya tidak. Memiliki keduanya hanya meningkatkan kebisingan.
BlueRaja - Danny Pflughoeft
3
apakah mungkin untuk dilakukan tanpa ToList()? Ini pembunuh
Toolkit
2
Apakah ToList () mendapatkan semua record dari database, sesuai dengan kondisinya, bukan? Jika benar, itu akan menjadi kinerja yang sangat buruk. Bagaimana jika ada jutaan catatan, kita memuatnya ke dalam memori untuk menjalankan fungsi ini? Harap perbaiki saya jika saya salah.
Jacob
20

Jangan gunakan ToList()metode seperti pada jawaban yang diterima!

Menjalankan profiler SQL, saya memverifikasi dan menemukan bahwa ToList()fungsi mendapatkan semua catatan dari database. Ini benar-benar kinerja yang buruk !!

Saya akan menjalankan kueri ini dengan perintah sql murni sebagai berikut:

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

Ini akan mengoperasikan pembaruan dalam satu tembakan tanpa memilih satu baris pun.

Yakub
sumber
3

Inilah yang saya lakukan:

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

Harapan membantu seseorang.

shaijut
sumber
Bekerja seperti pesona!
yu yang Jian
4
ini buruk, Anda memanggil database setiap kali untuk mengambil record featuredan juga Anda tidak boleh menambahkan context.SaveChanges()di foreachdalamnya harus berada di luar foreach loop.
Jawand Singh
1
SQL tidak sama dengan kode EF. Dalam SQL, hanya ada 1 perintah yang berjalan di semua baris dan memperbarui tabel. Kode EF mengambil semua baris terlebih dahulu, memperbarui yang diubah pada DB, yang berarti bahwa jika Anda memiliki 1000 baris yang diperbarui, itu akan mengeksekusi pembaruan 1000 sql
Ashkan Sirous
1
@stom Ini tidak masih sama :) context.SaveChanges (); kirimkan saja pembaruan Anda. masih akan ada 1000 perintah pembaruan masing-masing menggunakan id dan bukan kondisi SortOrder
Ashkan Sirous
2
@stom ExecuteSqlCommand ada di EF untuk tujuan ini tetapi pada saya setuju itu tidak cantik :) Bagaimanapun, maksud saya adalah bahwa Anda telah menulis perintah SQL dan kode EF-C # yang berbeda dan mengklaim bahwa mereka sama. :)
Ashkan Sirous