ฉันพยายามทำการวิจัยมากมาย แต่ฉันเป็นคนชอบ db มากกว่าดังนั้นแม้แต่คำอธิบายใน MSDN ก็ไม่สมเหตุสมผลกับฉันเลย ใครก็ได้โปรดอธิบายและให้ตัวอย่างบางส่วนเกี่ยวกับInclude()
คำแถลงในข้อกำหนดของSQL
สืบค้น
ฉันพยายามทำการวิจัยมากมาย แต่ฉันเป็นคนชอบ db มากกว่าดังนั้นแม้แต่คำอธิบายใน MSDN ก็ไม่สมเหตุสมผลกับฉันเลย ใครก็ได้โปรดอธิบายและให้ตัวอย่างบางส่วนเกี่ยวกับInclude()
คำแถลงในข้อกำหนดของSQL
สืบค้น
คำตอบ:
สมมติว่าคุณต้องการรับรายชื่อลูกค้าทั้งหมดของคุณ:
var customers = context.Customers.ToList();
และสมมติว่าแต่ละCustomer
ออบเจ็กต์มีการอ้างอิงถึงชุดของOrders
มันและแต่ละชิ้นOrder
มีการอ้างอิงLineItems
ซึ่งอาจอ้างถึง a Product
.
อย่างที่คุณเห็นการเลือกออบเจ็กต์ระดับบนสุดที่มีเอนทิตีที่เกี่ยวข้องจำนวนมากอาจส่งผลให้คิวรีต้องดึงข้อมูลจากหลายแหล่ง ในการวัดประสิทธิภาพInclude()
ช่วยให้คุณระบุว่าควรอ่านเอนทิตีที่เกี่ยวข้องใดจากฐานข้อมูลโดยเป็นส่วนหนึ่งของแบบสอบถามเดียวกัน
เมื่อใช้ตัวอย่างเดียวกันสิ่งนี้อาจทำให้เกิดส่วนหัวคำสั่งซื้อที่เกี่ยวข้องทั้งหมด แต่ไม่มีเรกคอร์ดอื่น ๆ :
var customersWithOrderDetail = context.Customers.Include("Orders").ToList();
เป็นจุดสุดท้ายตั้งแต่คุณขอ SQL คำสั่งแรกที่ไม่มีไม่Include()
สามารถสร้างคำสั่งง่ายๆ:
SELECT * FROM Customers;
คำสั่งสุดท้ายที่เรียกInclude("Orders")
อาจมีลักษณะดังนี้:
SELECT *
FROM Customers JOIN Orders ON Customers.Id = Orders.CustomerId;
LineItems
และProducts
แบบสอบถาม LINQ ควรมีลักษณะดังนี้: var customersWithOrderDetail = context.Customers.Include("Orders").Include("LineItems").Include("Products").ToList();
?
Include()
เพื่อจับวัตถุตาม "เส้นทาง" ที่แตกต่างกันได้ หากคุณต้องการให้ออบเจ็กต์อยู่ในเส้นทางเดียวกันคุณจะต้องทำการเรียกเพียงครั้งเดียวที่ระบุเส้นทางทั้งหมด เนื่องจากLineItems
และProducts
ไม่แชร์องค์ประกอบเส้นทางใด ๆ คุณจึงต้องมีการโทรแยก
ฉันแค่อยากจะเพิ่มว่า "รวม" เป็นส่วนหนึ่งของการโหลดอย่างกระตือรือร้น มีอธิบายไว้ในบทช่วยสอน Entity Framework 6 โดย Microsoft นี่คือลิงค์: https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-related-data-with-the -entity-framework-in-an-asp-net-mvc-application
ตัดตอนมาจากหน้าที่เชื่อมโยง:
นี่คือหลายวิธีที่ Entity Framework สามารถโหลดข้อมูลที่เกี่ยวข้องลงในคุณสมบัติการนำทางของเอนทิตี:
ขี้เกียจโหลด. เมื่ออ่านเอนทิตีเป็นครั้งแรกข้อมูลที่เกี่ยวข้องจะไม่ถูกเรียกคืน อย่างไรก็ตามในครั้งแรกที่คุณพยายามเข้าถึงคุณสมบัติการนำทางข้อมูลที่จำเป็นสำหรับคุณสมบัติการนำทางนั้นจะถูกดึงโดยอัตโนมัติ สิ่งนี้ส่งผลให้มีการสืบค้นหลายรายการที่ส่งไปยังฐานข้อมูล - หนึ่งรายการสำหรับเอนทิตีเองและอีกครั้งในแต่ละครั้งที่ต้องดึงข้อมูลที่เกี่ยวข้องสำหรับเอนทิตี คลาส DbContext เปิดใช้งานการโหลดแบบขี้เกียจตามค่าเริ่มต้น
กำลังโหลด เมื่ออ่านเอนทิตีข้อมูลที่เกี่ยวข้องจะถูกดึงมาด้วย โดยทั่วไปจะส่งผลให้มีคิวรีการรวมเดียวที่ดึงข้อมูลทั้งหมดที่จำเป็น คุณระบุการโหลดที่ต้องการโดยใช้
Include
วิธีการกำลังโหลดอย่างชัดเจน สิ่งนี้คล้ายกับการโหลดแบบขี้เกียจยกเว้นว่าคุณดึงข้อมูลที่เกี่ยวข้องในโค้ดอย่างชัดเจน จะไม่เกิดขึ้นโดยอัตโนมัติเมื่อคุณเข้าถึงคุณสมบัติการนำทาง คุณโหลดข้อมูลที่เกี่ยวข้องด้วยตนเองโดยรับรายการตัวจัดการสถานะอ็อบเจ็กต์สำหรับเอนทิตีและเรียกเมธอด Collection.Load สำหรับคอลเลกชันหรือเมธอด Reference.Load สำหรับคุณสมบัติที่เก็บเอนทิตีเดียว (ในตัวอย่างต่อไปนี้หากคุณต้องการโหลดคุณสมบัติการนำทางของผู้ดูแลระบบคุณจะแทนที่
Collection(x => x.Courses)
ด้วยReference(x => x.Administrator)
) โดยทั่วไปคุณจะใช้การโหลดแบบชัดแจ้งเฉพาะเมื่อคุณปิดการโหลดแบบขี้เกียจเนื่องจากไม่ได้ดึงค่าคุณสมบัติในทันทีการโหลดแบบขี้เกียจและการโหลดแบบชัดแจ้งจึงเรียกอีกอย่างว่าการโหลดแบบรอการตัดบัญชี
คิดว่าเป็นการบังคับใช้ Eager-Loading ในสถานการณ์ที่รายการย่อยของคุณจะขี้เกียจโหลด
Query EF กำลังส่งไปยังฐานข้อมูลจะให้ผลลัพธ์ที่ใหญ่กว่าในตอนแรก แต่ในการเข้าถึงจะไม่มีการสอบถามติดตามเมื่อเข้าถึงรายการที่รวมอยู่
ในทางกลับกันหากไม่มี EF จะดำเนินการค้นหาแยกในภายหลังเมื่อคุณเข้าถึงรายการย่อยเป็นครั้งแรก