Поделиться через


Отложенная и немедленная загрузка

При запросе к объекту фактически извлекается только запрошенный объект. Связанные объекты одновременно не извлекаются автоматически. (Дополнительные сведения см. в разделе "Запросы между связями".) Невозможно увидеть тот факт, что связанные объекты еще не загружены, так как попытка доступа к ним создает запрос, который извлекает их.

Например, может потребоваться запросить определенный набор заказов, а затем только иногда отправлять уведомление по электронной почте определенным клиентам. Вам не обязательно сначала нужно получить все данные клиента с каждым заказом. Вы можете использовать отложенную загрузку, чтобы задержать получение дополнительных сведений до тех пор, пока это не станет абсолютно необходимым. Рассмотрим следующий пример:

    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

Противоположность также может быть верной. Возможно, у вас есть приложение, которое одновременно просматривает данные клиента и заказа. Вы знаете, что вам нужны оба набора данных. Вы знаете, что ваше приложение нуждается в информации о заказах для каждого клиента сразу после получения результатов. Вы не хотите отправлять отдельные запросы для заказов для каждого клиента. Вам действительно нужно извлечь данные о заказах совместно с данными о клиентах.

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

Вы также можете присоединить клиентов и заказы в запросе, формируя кросс-продукт и извлекая все относительные биты данных в виде одной большой проекции. Но эти результаты не являются сущностями. (Дополнительные сведения см. в статье об объектной модели LINQ to SQL. Сущности — это объекты, имеющие идентичность и которые можно изменить, в то время как результаты будут проекциями, которые нельзя изменить или сохранить. Еще хуже, вы будете извлекать большое количество избыточных данных, поскольку информация о каждом клиенте повторяется для каждого заказа в результатах объединения с упрощенной структурой.

То, что вам действительно нужно, — это способ получения набора связанных объектов одновременно. Набор является выделенной частью графа, так что вы никогда не будете извлекать больше или меньше, чем это необходимо для вашего предполагаемого использования. Для этого LINQ to SQL обеспечивает DataLoadOptions немедленную загрузку области вашей объектной модели. Ниже перечислены используемые методы.

  • Метод LoadWith для немедленной загрузки данных, связанных с основным целевым объектом.

  • Метод AssociateWith для фильтрации объектов, полученных для определенного отношения.

См. также