Udostępnij przez


Opóźnione vs. natychmiastowe ładowanie

Podczas wykonywania zapytania o obiekt faktycznie pobierasz tylko żądany obiekt. Powiązane obiekty nie są pobierane automatycznie w tym samym czasie. (Aby uzyskać więcej informacji, zobacz Wykonywanie zapytań między relacjami). Nie widać faktu, że powiązane obiekty nie zostały jeszcze załadowane, ponieważ próba uzyskania do nich dostępu powoduje wygenerowanie żądania, które je pobiera.

Na przykład możesz chcieć wykonać zapytanie dotyczące określonego zestawu zamówień, a następnie tylko od czasu do czasu wysyłać powiadomienia e-mail do konkretnych klientów. Niekoniecznie musisz początkowo pobierać wszystkie dane klientów z każdym zamówieniem. Możesz użyć odroczonego ładowania, aby odroczyć pobieranie dodatkowych informacji, dopóki nie trzeba absolutnie tego robić. Rozważmy następujący przykład:

    Northwnd db = new Northwnd(@"northwnd.mdf");

    IQueryable<Order> notificationQuery =
    from ord in db.Orders
 where ord.ShipVia == 3
  select ord;

    foreach (Order ordObj in notificationQuery)
    {
        if (ordObj.Freight > 200)
            SendCustomerNotification(ordObj.Customer);
        ProcessOrder(ordObj);
    }
}
Dim db As New Northwnd("c:\northwnd.mdf")
Dim notificationQuery = _
    From ord In db.Orders _
    Where ord.ShipVia = 3 _
    Select ord

For Each ordObj As Order In notificationQuery
    If ordObj.Freight > 200 Then
        SendCustomerNotification(ordObj.Customer)
        ProcessOrder(ordObj)
    End If

Next

Przeciwieństwo może być również prawdziwe. Być może masz aplikację, która musi jednocześnie wyświetlać dane klienta i zamówienia. Wiesz, że potrzebne są oba zestawy danych. Wiesz, że aplikacja potrzebuje informacji o zamówieniu dla każdego klienta, gdy tylko uzyskasz wyniki. Nie chcesz przesyłać pojedynczych zapytań dotyczących zamówień dla każdego klienta. To, czego naprawdę chcesz, to pobrać dane zamówienia wraz z danymi klientów.

Northwnd db = new Northwnd(@"c:\northwnd.mdf");

db.DeferredLoadingEnabled = false;

IQueryable<Customer> custQuery =
    from cust in db.Customers
    where cust.City == "London"
    select cust;

foreach (Customer custObj in custQuery)
{
    foreach (Order ordObj in custObj.Orders)
    {
        ProcessCustomerOrder(ordObj);
    }
}
Dim db As New Northwnd("c:\northwnd.mdf")

db.DeferredLoadingEnabled = False

Dim custQuery = _
    From cust In db.Customers _
    Where cust.City = "London" _
    Select cust

For Each custObj As Customer In custQuery
    For Each ordObj As Order In custObj.Orders
        ProcessCustomerOrder(ordObj)
    Next
Next

Możesz również dołączyć klientów i zamówienia w zapytaniu, tworząc między produktami i pobierając wszystkie względne bity danych jako jedną dużą projekcję. Ale te wyniki nie są jednostkami. (Aby uzyskać więcej informacji, zobacz LINQ to SQL Object Model). Jednostki to obiekty, które mają tożsamość i które można modyfikować, podczas gdy te wyniki będą projekcjami, których nie można zmienić i utrwalić. Co więcej, pobierasz wiele nadmiarowych danych, ponieważ każdy klient i każde zamówienie powtarzane są w spłaszczonym wyniku sprzężenia.

To, czego naprawdę potrzebujesz, to sposób pobierania zestawu powiązanych obiektów w tym samym czasie. Zestaw to wydzielona sekcja wykresu, abyś nigdy nie pobierał ani więcej, ani mniej niż było konieczne do zamierzonego użycia. W tym celu LINQ to SQL zapewnia DataLoadOptions do natychmiastowego ładowania części modelu obiektowego. Metody obejmują:

  • Metoda LoadWith do natychmiastowego załadowania danych powiązanych z głównym celem.

  • Metoda AssociateWith, służąca do filtrowania obiektów pobranych dla określonej relacji.

Zobacz także

  • pojęcia dotyczące zapytań