Carregamento diferido versus imediato

Quando você consulta um objeto, na verdade recupera apenas o objeto solicitado. Os objetos relacionados não são buscados automaticamente ao mesmo tempo. (Para obter mais informações, consulte Consultando entre relacionamentos.) Você não pode ver o fato de que os objetos relacionados ainda não estão carregados, porque uma tentativa de acessá-los produz uma solicitação que os recupera.

Por exemplo, você pode querer consultar um determinado conjunto de pedidos e, em seguida, apenas ocasionalmente enviar uma notificação por e-mail para clientes específicos. Você não precisaria necessariamente inicialmente recuperar todos os dados do cliente a cada pedido. Você pode usar o carregamento diferido para adiar a recuperação de informações extras até que seja absolutamente necessário. Considere o seguinte exemplo:

    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

O contrário também pode ser verdadeiro. Você pode ter um aplicativo que precisa visualizar dados de clientes e pedidos ao mesmo tempo. Você sabe que precisa de ambos os conjuntos de dados. Você sabe que seu aplicativo precisa de informações de pedido para cada cliente assim que obtiver os resultados. Você não gostaria de enviar consultas individuais para pedidos para cada cliente. O que você realmente quer é recuperar os dados do pedido junto com os clientes.

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

Você também pode unir clientes e pedidos em uma consulta formando o produto cruzado e recuperando todos os bits relativos de dados como uma grande projeção. Mas estes resultados não são entidades. (Para obter mais informações, consulte O modelo de objeto LINQ to SQL). Entidades são objetos que têm identidade e que você pode modificar, enquanto esses resultados seriam projeções que não podem ser alteradas e persistidas. Pior ainda, você estaria recuperando muitos dados redundantes à medida que cada cliente repete para cada pedido na saída de junção nivelada.

O que você realmente precisa é uma maneira de recuperar um conjunto de objetos relacionados ao mesmo tempo. O conjunto é uma seção delineada de um gráfico para que você nunca esteja recuperando mais ou menos do que o necessário para o uso pretendido. Para isso, o LINQ to SQL fornece DataLoadOptions o carregamento imediato de uma região do seu modelo de objeto. Os métodos incluem:

  • O LoadWith método, para carregar imediatamente os dados relacionados ao alvo principal.

  • O AssociateWith método, para filtrar objetos recuperados para uma relação específica.

Consulte também