推迟加载与即时加载Deferred versus Immediate Loading

查询某对象时,实际上您只检索请求的对象。When you query for an object, you actually retrieve only the object you requested. 不会同时自动提取相关的对象。The related objects are not automatically fetched at the same time. (有关详细信息,请参阅跨关系查询。)您无法看到相关对象尚未加载这一事实,原因是尝试访问它们时将产生检索它们的请求。(For more information, see Querying Across Relationships.) You cannot see the fact that the related objects are not already loaded, because an attempt to access them produces a request that retrieves them.

例如,你可能需要查询一组特定的订单,然后仅偶尔向特定客户发送电子邮件通知。For example, you might want to query for a particular set of orders and then only occasionally send an email notification to particular customers. 您最初不一定需要检索与每个订单有关的所有客户数据。You would not necessarily need initially to retrieve all customer data with every order. 您可以使用延迟加载将额外信息的检索操作延迟到您确实需要检索它们时再进行。You can use deferred loading to defer retrieval of extra information until you absolutely have to. 请看下面的示例:Consider the following example:

    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

反过来也可能是可行的。The opposite might also be true. 您的应用程序可能必须同时查看客户数据和订单数据。You might have an application that has to view customer and order data at the same time. 您了解同时需要这两组数据。You know you need both sets of data. 您了解一旦获得结果,您的应用程序就需要每个客户的订单信息。You know your application needs order information for each customer as soon as you get the results. 您不希望一个一个地提交对每个客户的订单的查询。You would not want to submit individual queries for orders for every customer. 您真正想要的是将订单数据与客户信息一起检索出来。What you really want is to retrieve the order data together with the customers.

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

您还可以在查询中联接客户和订单,方法是构建叉积并将所有相关数据位作为一个大型投影检索出来。You can also join customers and orders in a query by forming the cross-product and retrieving all the relative bits of data as one large projection. 但这些结果并非实体。But these results are not entities. (有关详细信息,请参阅LINQ to SQL 对象模型)。(For more information, see The LINQ to SQL Object Model). 实体是具有标识且您可以修改的对象,而这些结果将是无法更改和持久化的投影。Entities are objects that have identity and that you can modify, whereas these results would be projections that cannot be changed and persisted. 更糟的是,您将检索到大量的冗余数据,因为在平展联接输出中,对于每个订单,每个客户将重复出现。Even worse, you would be retrieving lots of redundant data as each customer repeats for each order in the flattened join output.

您真正需要的是同时检索相关对象的集合的方法。What you really need is a way to retrieve a set of related objects at the same time. 此集合是关系图的精确剖面,因此您检索到的数据绝不会比您所需要的数据多或少。The set is a delineated section of a graph so that you would never be retrieving more or less than was necessary for your intended use. 为此,LINQ to SQLLINQ to SQL 提供了 DataLoadOptions,用以立即加载对象模型的某一区域。For this purpose, LINQ to SQLLINQ to SQL provides DataLoadOptions for immediate loading of a region of your object model. 方法包括:Methods include:

  • LoadWith 方法,用于立即加载与主目标相关的数据。The LoadWith method, to immediately load data related to the main target.

  • AssociateWith 方法,用于筛选为特定关系检索到的对象。The AssociateWith method, to filter objects retrieved for a particular relationship.

请参阅See also