จะบังคับให้ Entity Framework รับข้อมูลที่อัปเดตจากฐานข้อมูลได้อย่างไร?


91

ฉันกำลังใช้EntityFramework.Extended library เพื่อทำการอัพเดตเป็นกลุ่ม ปัญหาเดียวคือ EF ไม่ติดตามการอัปเดตแบตช์ที่ดำเนินการโดยไลบรารี ดังนั้นเมื่อฉันสอบถามDbContextอีกครั้งจะไม่ส่งคืนเอนทิตีที่อัปเดต

ฉันพบว่าการใช้AsNoTracking()วิธีการในขณะที่สอบถามจะปิดใช้งานการติดตามและรับข้อมูลใหม่จากฐานข้อมูล อย่างไรก็ตามเนื่องจาก EF ไม่ได้ติดตามเอนทิตีที่สอบถามAsNoTracking()ฉันจึงไม่สามารถทำการอัปเดตข้อมูลที่สอบถามได้

มีวิธีใดที่จะบังคับให้ EF รับข้อมูลล่าสุดขณะติดตามการเปลี่ยนแปลง


2
ดู 29k ครั้งและมีเพียง 19 upvotes เกี่ยวกับเรื่องนี้ ... ดีฉันเพิ่มของฉันอยู่ดี
jleach

คำตอบ:


152

โปรดลองสิ่งนี้เพื่อรีเฟรชเอนทิตีเดียว:

Context.Entry<T>(entity).Reload()

แก้ไข: ในการรับข้อมูลใหม่สำหรับคอลเลกชันของเอนทิตีควรพยายามกำจัดDbContextอินสแตนซ์หลังจากการร้องขอแต่ละครั้ง


ขอขอบคุณ! มีวิธีใดในการโหลดคอลเลกชันของเอนทิตีมากกว่าหนึ่งรายการหรือไม่? DbSetโดยเฉพาะอย่างยิ่งทั้ง
Saravana

มีอะไรอีกบ้างที่คุณต้องการเพื่อให้ถือว่าเป็นคำตอบ?
PlTaylor

1
ใช่ แต่ยังไม่แสดงวิธีโหลดคอลเล็กชันของเอนทิตีซ้ำ
Saravana

1
คุณได้ลองทิ้ง dbcontext ของคุณและสร้างใหม่หรือไม่?
PlTaylor

3
ใช้เวลาหลายชั่วโมงกว่าจะได้ข้อสรุปนี้ การแก้ไขในคำตอบคือสิ่งที่ช่วยให้ฉันพบวิธีแก้ปัญหา ขอบคุณ!
BeemerGuy

17

ฉันสะดุดกับคำถามนี้ในขณะที่ค้นหาวิธีแก้ปัญหาที่ฉันพบโดยที่คุณสมบัติการนำทางไม่ได้รับการเติมข้อมูลหลังจากอัปเดตเอนทิตี เมื่อใดก็ตามที่ฉันพยายามโหลดเอนทิตีใหม่จากฐานข้อมูลมันจะดึงรายการจากร้านค้าในพื้นที่แทนซึ่งจะไม่เติมคุณสมบัติการนำทางผ่านการโหลดแบบขี้เกียจ แทนที่จะทำลายบริบทและสร้างใหม่ฉันพบว่าสิ่งนี้ทำให้ฉันได้รับข้อมูลใหม่โดยที่พร็อกซีใช้งานได้:

_db.Entry(entity).State = EntityState.Detached;

ตรรกะเบื้องหลังคือ - การอัปเดตของฉันแนบเอนทิตีเพื่อให้ติดตามการเปลี่ยนแปลง สิ่งนี้จะเพิ่มไปยังร้านค้าในพื้นที่ หลังจากนั้นความพยายามใด ๆ ในการดึงข้อมูลเอนทิตีด้วยพร็อกซีที่ใช้งานได้จะส่งผลให้เอนทิตีดึงข้อมูลในเครื่องแทนที่จะออกไปที่ฐานข้อมูลและส่งคืนเอนทิตีใหม่ที่เปิดใช้งานพร็อกซี ฉันลองใช้ตัวเลือกรีโหลดด้านบนซึ่งจะรีเฟรชวัตถุจากฐานข้อมูล แต่นั่นไม่ได้ให้วัตถุพร็อกซีที่มีการโหลดแบบขี้เกียจ ฉันลองทำไฟล์Find(id), Where(t => t.Id = id), First(t => t.Id = id). ในที่สุดฉันตรวจสอบสถานะที่มีอยู่ที่ระบุและเห็นว่ามีสถานะ "แยกออก" ยูเรก้า! หวังว่านี่จะช่วยใครบางคนได้


คุณใช้สถานะแยกเพื่อให้การโหลดขี้เกียจทำงานที่ไหน ฉันลองวิธีแก้ปัญหาของคุณแล้ว แต่มันไม่ได้ผลสำหรับฉันฉันต้องพลาดอะไรบางอย่าง ความช่วยเหลือของคุณจะได้รับการชื่นชม
Rex

2
ฉันคิดออกแล้ว: 1. บันทึกเอนทิตี 2. ตั้งค่าสถานะเป็นแยกออก 3. อ่านเอนทิตีจากฐานข้อมูล ขอบคุณสำหรับคำแนะนำ!
Rex

1

การทำให้โค้ดทำงานบนบริบทเดียวกันจะไม่ทำให้คุณได้รับการอัปเดตเอนทิตี มันจะต่อท้ายเอนทิตีใหม่ที่สร้างในฐานข้อมูลระหว่างการรันเท่านั้น EF force reload สามารถทำได้ดังนี้:

ObjectQuery _query = Entity.MyEntity;
_query.MergeOption = MergeOption.OverwriteChanges;
var myEntity = _query.Where(x => x.Id > 0).ToList();

1

ฉันประกาศตัวแปรเอนทิตีโดยไม่มีการกำหนดเป็นส่วนหนึ่งของคลาส สิ่งนี้ทำให้ฉันสามารถกำจัดอินสแตนซ์ได้โดยไม่สูญเสียตัวแปรสำหรับการอ้างอิงด้วยวิธีการอื่น ฉันเพิ่งเจอสิ่งนี้ดังนั้นมันจึงไม่มีรันไทม์มากนักภายใต้เข็มขัด แต่จนถึงตอนนี้ดูเหมือนว่าจะใช้งานได้ดี

public partial class frmMyForm
{
    private My_Entities entity;

    public frmMyForm()
    {
        InitializeComponent();
    }

    private void SomeControl_Click(object sender, EventArgs e)
    {
        db.SaveChanges();
        db.Dispose();
        entity = new My_Entities();
        //more code using entity ...
}

0

สำหรับฉัน ... ฉันเข้าถึง DbContext ของฉันดังนี้:

_viewModel.Repo.Context

ในการบังคับให้ EF เข้าสู่ฐานข้อมูลฉันทำสิ่งนี้:

_viewModel.Repo.Context = new NewDispatchContext();

เขียนทับ DbContext ปัจจุบันด้วยอินสแตนซ์ใหม่ จากนั้นในครั้งต่อไปที่ฉันใช้บริการข้อมูลของฉันพวกเขาจะได้รับข้อมูลจากฐานข้อมูล

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