อัปเดตหลายแถวใน Entity Framework จากรายการรหัส


95

ฉันกำลังพยายามสร้างแบบสอบถามสำหรับกรอบงานเอนทิตีที่จะช่วยให้ฉันสามารถจดรายการรหัสและอัปเดตฟิลด์ที่เกี่ยวข้องได้

ตัวอย่างใน SQL:

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

ฉันจะแปลงข้างต้นเป็นกรอบงานเอนทิตีได้อย่างไร


Oracle mysql แพลตฟอร์มฐานข้อมูลของคุณคืออะไร ..
zee

ฐานข้อมูลของฉันคือ Microsoft SQL
allencoded

: มีสองโครงการมาเปิดอนุญาตให้นี้EntityFramework.Extendedและอีntity กรอบส่วนขยาย
Peter Kerr

คำตอบเดียวที่ถูกต้องคือคุณทำไม่ได้ แน่นอนว่าคุณสามารถดึงข้อมูลที่ตรงกันทั้งหมดFriendจากฐานข้อมูลและอัปเดตคุณสมบัติmsgSentByและบันทึกการเปลี่ยนแปลงได้ แต่ EF จะส่งUPDATEข้อความสำหรับแต่ละบันทึก นั่นไม่เหมือนกับการอัปเดตจำนวนมากแบบคำสั่งเดียว ตามที่กล่าวไว้ให้มองหาไลบรารีของบุคคลที่สามที่มีการอัปเดตจำนวนมาก
เกิร์ตอาร์โนลด์

คำตอบ:


167

บางอย่างเช่นด้านล่าง

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

ฉันสามารถอัปเดตมากกว่าหนึ่งฟิลด์ใน foreach ด้านบนที่คุณเพิ่งส่งไปซึ่งเป็นสิ่งที่ฉันขอ แค่อยากรู้ว่าคุณสามารถทำอะไรได้มากกว่านี้? ดูเหมือนว่า SubmitChanges จะไม่ทำงานอีกต่อไป ฉันกำลังใช้กรอบงานเอนทิตีล่าสุด อาจจะ SaveChanges ()?
allencoded

10
ForEachเป็นวิธีการที่เปิดใช้Listงานและโดยทั่วไปไม่แนะนำให้ใช้เนื่องจากไม่ใช่วิธีการเขียนโปรแกรมที่ใช้งานได้จริง เพียงแค่ใช้foreach (ตัวดำเนินการ)เหมือนคนทั่วไป
BlueRaja - Danny Pflughoeft

55
การใช้โซลูชันนี้จะสร้างแบบสอบถามการอัปเดตหนึ่งรายการสำหรับแต่ละองค์ประกอบในรายการ มีวิธีทำให้ EF ทำแบบสอบถามเพียงคำเดียวเหมือนในคำถามหรือไม่? ( UPDATE SomeTable SET SomeField = SomeValue WHERE Id IN (...))
RamNow

19
โปรดทราบว่านี่เป็นวิธีที่ไม่มีประสิทธิภาพในการดำเนินการนี้จากมุมมองของฐานข้อมูล ปัญหานี้ไม่เพียง แต่ออกคำสั่ง select ขนาดใหญ่ที่เกี่ยวข้องกับทุกแถวจากตาราง Friends แต่ยังออกคำสั่ง UPDATE แยกต่างหากสำหรับทุกระเบียนที่อัปเดต ดังนั้นแทนที่จะออกคำสั่งเดียวคุณจะพบปัญหาหลายคำสั่งรวมทั้งการสตรีมข้อมูลจำนวนมากจากฐานข้อมูลของคุณ
d512

1
@ShekharPankaj โดยพื้นฐานแล้วสิ่งที่คุณต้องการทำคือออกคำสั่ง SQL เช่น "UPDATE Friends SET msgSentBy = '1234' WHERE ID IN (1, 2, 3, 4)" ฉันไม่คิดว่า EF ได้รับการสนับสนุนโดยตรงสำหรับการทำเช่นนั้น ฉันเชื่อว่ามีโซลูชันของบุคคลที่สามสำหรับสิ่งนี้ ( stackoverflow.com/questions/12751258/batch-update-delete-ef5 ) แต่ฉันไม่ได้ใช้ ตัวเลือกอื่น ๆ คือการใช้ ADO.NET แบบดิบแทน EF
d512

-1
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()

โดยทั่วไปคุณมักจะใช้วิธี async โดยรอการสืบค้น db


ฉันไม่เห็นว่าสิ่งนี้เพิ่มอะไรให้กับคำตอบที่มีอยู่ โดยพื้นฐานแล้วมันก็ทำซ้ำ
Gert Arnold

ความแตกต่างที่สำคัญคือการใช้ foreach แทนเพื่อน ForEach
Raphael Pinel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.