Bao gồm () làm gì trong LINQ?


93

Tôi đã cố gắng thực hiện rất nhiều nghiên cứu nhưng tôi là một gã db hơn - vì vậy ngay cả lời giải thích trong MSDN cũng không có ý nghĩa gì đối với tôi. Bất cứ ai có thể vui lòng giải thích và cung cấp một số ví dụ về Include()câu lệnh gì trong thuật ngữ SQLtruy vấn không?


Rất cơ bản, tôi chỉ biết đơn giản Chọn, Ở đâu, Đặt hàng theo, một số người phản đối tổng hợp. Tôi chưa thử tham gia vào LINQ, cũng như Bao gồm. Mục tiêu cuối cùng của tôi là để có thể viết lại những LINQ truy vấn vào SQL
CJ

Câu trả lời:


165

Ví dụ: giả sử bạn muốn có danh sách tất cả khách hàng của mình:

var customers = context.Customers.ToList();

Và giả sử rằng mỗi Customerđối tượng có một tham chiếu đến tập hợp của nó Orders, và mỗi đối tượng Ordercó tham chiếu đến LineItemsmà cũng có thể tham chiếu a Product.

Như bạn thấy, việc chọn một đối tượng cấp cao nhất có nhiều thực thể liên quan có thể dẫn đến một truy vấn cần lấy dữ liệu từ nhiều nguồn. Là một thước đo hiệu suất, Include()cho phép bạn chỉ ra các thực thể liên quan nào nên được đọc từ cơ sở dữ liệu như một phần của cùng một truy vấn.

Sử dụng cùng một ví dụ, điều này có thể mang lại tất cả các tiêu đề đơn hàng có liên quan, nhưng không có bản ghi nào khác:

var customersWithOrderDetail = context.Customers.Include("Orders").ToList();

Điểm cuối cùng kể từ khi bạn yêu cầu SQL, câu lệnh đầu tiên không có câu lệnh có Include()thể tạo ra một câu lệnh đơn giản:

SELECT * FROM Customers;

Câu lệnh cuối cùng mà các cuộc gọi Include("Orders")có thể trông giống như sau:

SELECT *
FROM Customers JOIN Orders ON Customers.Id = Orders.CustomerId;

1
Cảm ơn bạn. Sử dụng ví dụ của bạn, tôi có thể nói nếu tôi cũng muốn bao gồm LineItemsProducts, truy vấn LINQ sẽ trông giống như sau var customersWithOrderDetail = context.Customers.Include("Orders").Include("LineItems").Include("Products").ToList();:?
CJ

2
Có, bạn có thể xâu chuỗi nhiều lệnh gọi Include()để chụp các đối tượng dọc theo các "đường dẫn" khác nhau. Nếu bạn muốn các đối tượng trong cùng một đường dẫn, bạn chỉ phải thực hiện một lệnh gọi chỉ định toàn bộ đường dẫn. Vì LineItemsProductskhông chia sẻ bất kỳ thành phần đường dẫn nào nên bạn cần các cuộc gọi riêng biệt.
Yuck

Có bắt buộc phải sử dụng Bao gồm không? Tôi khá chắc chắn rằng tôi đã làm việc trên các giải pháp mà tôi có thể lấy các đối tượng liên quan mà không cần sử dụng nó.
Jepzen

@Jepzen Nó phụ thuộc vào việc bạn có đang sử dụng các thực thể được tải chậm hay không.
Yuck

@Yuck, tôi tin rằng điều này hoạt động khi bạn đang sử dụng lazy-loading, trong trường hợp tải nhanh, bạn không cần sử dụng câu lệnh "include", nhưng điều này chắc chắn sẽ dẫn đến các vấn đề về hiệu suất. Xin hãy sửa cho tôi về điều này.
sam

27

Tôi chỉ muốn thêm rằng "Bao gồm" là một phần của quá trình tải háo hức. Nó được mô tả trong hướng dẫn Entity Framework 6 của Microsoft. Đây là liên kết: https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-inity-data-with-the -entity-framework-in-an-asp-net-mvc-application


Trích từ trang liên kết:

Dưới đây là một số cách mà Khung thực thể có thể tải dữ liệu liên quan vào các thuộc tính điều hướng của một thực thể:

Tải chậm. Khi thực thể được đọc lần đầu tiên, dữ liệu liên quan sẽ không được truy xuất. Tuy nhiên, lần đầu tiên bạn cố gắng truy cập thuộc tính điều hướng, dữ liệu cần thiết cho thuộc tính điều hướng đó sẽ tự động được truy xuất. Điều này dẫn đến nhiều truy vấn được gửi đến cơ sở dữ liệu - một truy vấn cho chính thực thể và một truy vấn mỗi lần dữ liệu liên quan cho thực thể phải được truy xuất. Lớp DbContext cho phép tải chậm theo mặc định.

Đang tải háo hức. Khi thực thể được đọc, dữ liệu liên quan được truy xuất cùng với nó. Điều này thường dẫn đến một truy vấn kết hợp duy nhất lấy tất cả dữ liệu cần thiết. Bạn chỉ định tải mong muốn bằng cách sử dụng Includephương pháp này.

Đang tải rõ ràng. Điều này tương tự như tải chậm, ngoại trừ việc bạn truy xuất rõ ràng dữ liệu liên quan trong mã; nó không tự động xảy ra khi bạn truy cập thuộc tính điều hướng. Bạn tải dữ liệu liên quan theo cách thủ công bằng cách lấy mục nhập trình quản lý trạng thái đối tượng cho một thực thể và gọi phương thức Collection.Load cho các tập hợp hoặc phương thức Reference.Load cho các thuộc tính chứa một thực thể duy nhất. (Trong ví dụ sau, nếu bạn muốn tải thuộc tính điều hướng Quản trị viên, bạn sẽ thay thế Collection(x => x.Courses)bằngReference(x => x.Administrator) .) Thông thường, bạn chỉ sử dụng tính năng tải rõ ràng khi bạn đã tắt tính năng tải chậm.

Bởi vì chúng không truy xuất ngay lập tức các giá trị thuộc tính, tải chậm và tải rõ ràng còn được gọi là tải chậm.


3
Chào mừng bạn đến với SO =) Chỉ là một gợi ý nhưng khi bạn trả lời những câu đại loại như vậy, nếu có thể, hãy kèm theo một đoạn mã. Các liên kết có thể bị chết một cách đáng tiếc.
The_Cthulhu_Kid

2

Hãy coi nó giống như việc thực thi Eager-Loading trong một trường hợp mà nếu không các mục con của bạn sẽ tải chậm.

Truy vấn EF đang gửi đến cơ sở dữ liệu sẽ mang lại kết quả lớn hơn lúc đầu, nhưng khi truy cập sẽ không có truy vấn tiếp theo nào được thực hiện khi truy cập các mục được bao gồm.

Mặt khác, nếu không có nó, EF sẽ thực hiện các truy vấn riêng biệt sau này, khi bạn truy cập các mục con lần đầu tiên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.