ฉันต้องการชี้แจงบางสิ่งเนื่องจากคำตอบที่ขัดแย้งกันดูเหมือนจะเกิดขึ้น
(1) IQueryable
ขยายIEnumerable
ส่วนต่อประสาน (คุณสามารถส่งIQueryable
สิ่งที่คาดหวังIEnumerable
โดยไม่มีข้อผิดพลาด)
(2) ทั้งคู่IQueryable
และIEnumerable
LINQ พยายามทำการโหลดอย่างเกียจคร้านเมื่อวนซ้ำชุดผลลัพธ์ (โปรดทราบว่าการใช้งานสามารถเห็นได้ในวิธีการขยายส่วนต่อประสานสำหรับแต่ละประเภท)
ในคำอื่น ๆIEnumerables
ไม่ได้เป็นเพียง "ในหน่วยความจำ" IQueryables
ไม่ได้ถูกเรียกใช้งานบนฐานข้อมูลเสมอไป IEnumerable
จะต้องโหลดสิ่งต่าง ๆ ลงในหน่วยความจำ (เมื่อดึงออกมาอาจเป็นไปอย่างขี้เกียจ) เพราะไม่มีผู้ให้บริการข้อมูลที่เป็นนามธรรม IQueryables
พึ่งพาผู้ให้บริการที่เป็นนามธรรม (เช่น LINQ-to-SQL) แม้ว่าสิ่งนี้อาจเป็นผู้ให้บริการในหน่วยความจำ. NET
ตัวอย่างการใช้งาน
(a) ดึงรายการบันทึกIQueryable
จากบริบทของ EF (ไม่มีบันทึกอยู่ในหน่วยความจำ)
(ข) ผ่านไปยังมุมมองที่มีรูปแบบเป็นIQueryable
IEnumerable
(ถูกต้องIQueryable
ขยายIEnumerable
)
(c) วนซ้ำและเข้าถึงระเบียนของเอนทิตีลูกและคุณสมบัติของชุดข้อมูลจากมุมมอง (อาจทำให้เกิดข้อยกเว้น!)
ปัญหาที่เป็นไปได้
(1) IEnumerable
ความพยายามโหลดขี้เกียจและบริบทข้อมูลของคุณหมดอายุ มีข้อผิดพลาดเกิดขึ้นเนื่องจากไม่มีผู้ให้บริการอีกต่อไป
(2) พร็อกซีเอนทิตีของ Entity Framework เปิดใช้งาน (ค่าเริ่มต้น) และคุณพยายามเข้าถึงวัตถุที่เกี่ยวข้อง (เสมือน) ที่มีบริบทข้อมูลที่หมดอายุ เช่นเดียวกับ (1)
(3) ชุดผลลัพธ์ที่ใช้งานอยู่หลายชุด (MARS) หากคุณกำลังวนซ้ำIEnumerable
ในforeach( var record in resultSet )
บล็อกและพยายามเข้าถึงพร้อมกันrecord.childEntity.childProperty
คุณอาจลงเอยด้วย MARS เนื่องจากการโหลดชุดข้อมูลและเอนทิตีสัมพันธ์ สิ่งนี้จะทำให้เกิดข้อยกเว้นหากไม่ได้เปิดใช้งานในสตริงการเชื่อมต่อของคุณ
สารละลาย
- ฉันพบว่าการเปิดใช้งาน MARS ในสตริงการเชื่อมต่อนั้นใช้งานไม่ได้ ฉันขอแนะนำให้คุณหลีกเลี่ยง MARS เว้นแต่จะมีความเข้าใจและต้องการอย่างชัดเจน
ดำเนินการค้นหาและจัดเก็บผลลัพธ์โดยการเรียกใช้resultList = resultSet.ToList()
นี่เป็นวิธีที่ตรงไปตรงมาที่สุดในการรับรองเอนทิตีของคุณในหน่วยความจำ
ในกรณีที่คุณกำลังเข้าถึงหน่วยงานที่เกี่ยวข้องคุณอาจต้องใช้บริบทข้อมูล ทั้งที่หรือคุณสามารถปิดผู้รับมอบฉันทะนิติบุคคลและชัดเจนหน่วยงานที่เกี่ยวข้องจากคุณInclude
DbSet