Próbowałem przeprowadzić wiele badań, ale jestem bardziej typem db - więc nawet wyjaśnienie w MSDN nie ma dla mnie żadnego sensu. Czy ktoś może wyjaśnić i podać kilka przykładów, jakie Include()
stwierdzenie robi w SQL
zapytaniu?
Próbowałem przeprowadzić wiele badań, ale jestem bardziej typem db - więc nawet wyjaśnienie w MSDN nie ma dla mnie żadnego sensu. Czy ktoś może wyjaśnić i podać kilka przykładów, jakie Include()
stwierdzenie robi w SQL
zapytaniu?
Odpowiedzi:
Załóżmy na przykład, że chcesz uzyskać listę wszystkich swoich klientów:
var customers = context.Customers.ToList();
I załóżmy, że każdy Customer
obiekt ma odniesienie do swojego zbioru Orders
i że każdy Order
ma odniesienia, do LineItems
których może również odnosić się plik Product
.
Jak widać, wybranie obiektu najwyższego poziomu z wieloma powiązanymi jednostkami może skutkować zapytaniem, które będzie musiało pobrać dane z wielu źródeł. Jako miara wydajności Include()
umożliwia wskazanie, które powiązane jednostki powinny być odczytywane z bazy danych w ramach tego samego zapytania.
Korzystając z tego samego przykładu, może to spowodować wprowadzenie wszystkich powiązanych nagłówków zamówień, ale żadnych innych rekordów:
var customersWithOrderDetail = context.Customers.Include("Orders").ToList();
Na koniec, ponieważ poprosiłeś o SQL, pierwsza instrukcja bez Include()
może wygenerować prostą instrukcję:
SELECT * FROM Customers;
Końcowe stwierdzenie, które wywołuje, Include("Orders")
może wyglądać tak:
SELECT *
FROM Customers JOIN Orders ON Customers.Id = Orders.CustomerId;
LineItems
i Products
, zapytanie LINQ powinno wyglądać następująco var customersWithOrderDetail = context.Customers.Include("Orders").Include("LineItems").Include("Products").ToList();
:?
Include()
celu przechwytywania obiektów wzdłuż różnych „ścieżek”. Jeśli chcesz, aby obiekty znajdowały się na tej samej ścieżce, musisz wykonać tylko jedno wywołanie, które określa całą ścieżkę. Ponieważ LineItems
i Products
nie współdzielą żadnych komponentów ścieżki, potrzebujesz oddzielnych wywołań.
Chciałem tylko dodać, że „Uwzględnij” jest częścią niecierpliwego ładowania. Jest to opisane w samouczku Entity Framework 6 firmy Microsoft. Oto link: 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
Fragment z połączonej strony:
Oto kilka sposobów, w jakie Entity Framework może ładować powiązane dane do właściwości nawigacji jednostki:
Powolne ładowanie. Gdy jednostka jest odczytywana po raz pierwszy, powiązane dane nie są pobierane. Jednak przy pierwszej próbie uzyskania dostępu do właściwości nawigacji dane wymagane dla tej właściwości nawigacji są pobierane automatycznie. Powoduje to wysłanie wielu zapytań do bazy danych - jednego dla samej jednostki i za każdym razem, gdy trzeba pobrać powiązane dane dla jednostki. Klasa DbContext domyślnie włącza leniwe ładowanie.
Chętne ładowanie. Gdy jednostka jest odczytywana, wraz z nią pobierane są powiązane dane. Zwykle powoduje to pojedyncze zapytanie sprzężenia, które pobiera wszystkie potrzebne dane. Określasz zachłanne ładowanie za pomocą
Include
metody.Jawne ładowanie. Jest to podobne do ładowania z opóźnieniem, z tą różnicą, że jawnie pobierasz powiązane dane w kodzie; nie dzieje się to automatycznie po uzyskaniu dostępu do właściwości nawigacji. Możesz ładować powiązane dane ręcznie, pobierając wpis menedżera stanu obiektu dla jednostki i wywołując metodę Collection.Load dla kolekcji lub metodę Reference.Load dla właściwości, które przechowują pojedynczą jednostkę. (W poniższym przykładzie, jeśli chcesz załadować właściwość nawigacji administratora, zamień
Collection(x => x.Courses)
ją naReference(x => x.Administrator)
.) Zwykle jawne ładowanie będzie używane tylko wtedy, gdy wyłączysz ładowanie z opóźnieniem.Ponieważ nie pobierają natychmiast wartości właściwości, ładowanie z opóźnieniem i ładowanie jawne są również nazywane ładowaniem odroczonym.
Potraktuj to jako wymuszanie szybkiego ładowania w scenariuszu, w którym podelementy ładowałyby się leniwie.
Kwerenda EF wysyła do bazy danych na początku przyniesie większy wynik, ale podczas uzyskiwania dostępu nie będą wykonywane żadne dalsze zapytania podczas uzyskiwania dostępu do uwzględnionych elementów.
Z drugiej strony bez tego EF wykonywałby oddzielne zapytania później, kiedy po raz pierwszy uzyskasz dostęp do elementów podrzędnych.