远程查询执行与本地执行

你可以决定远程执行查询(即数据库引擎对数据库执行查询)或本地执行查询(LINQ to SQL 对本地缓存执行查询)。

远程执行

请考虑下列查询:

            Northwnd db = new Northwnd(@"northwnd.mdf");
            Customer c = db.Customers.Single(x => x.CustomerID == "19283");
foreach (Order ord in
    c.Orders.Where(o => o.ShippedDate.Value.Year == 1998))
{
    // Do something.
}
    Dim db As New Northwnd("c:\northwnd.mdf")
    Dim c As Customer = _
(From cust In db.Customers _
 Where cust.CustomerID = 19283).First()
    Dim orders = From ord In c.Orders _
                 Where ord.ShippedDate.Value.Year = 1998
    For Each nextOrder In orders
        ' Do something.
    Next

如果数据库有数千行订单,则在处理其中很小一部分时您不需要将它们全都检索出来。 在 LINQ to SQL 中, EntitySet<TEntity> 类实现了 IQueryable 接口。 这种方式确保了可以以远程方式执行此类查询。 利用此技术有两大优点:

  • 不会检索到不需要的数据。

  • 由于利用了数据库索引,由数据库引擎执行的查询通常更为高效。

本地执行

在其他一些情况下,您可能需要在本地缓存中保留完整的相关实体集。 为此,EntitySet<TEntity> 提供了 Load 方法,用于显式加载 EntitySet<TEntity> 的所有成员。

如果 EntitySet<TEntity> 已经加载,则后续查询将在本地执行。 这种方式在两个方面起到帮助作用:

  • 如果此完整集必须在本地使用或使用多次,则您可以避免远程查询和与之相关的延迟。

  • 实体可以序列化为完整的实体。

下面的代码段演示了如何实现本地执行:

            Northwnd db = new Northwnd(@"northwnd.mdf");
            Customer c = db.Customers.Single(x => x.CustomerID == "19283");
c.Orders.Load();

foreach (Order ord in
    c.Orders.Where(o => o.ShippedDate.Value.Year == 1998))
{
    // Do something.
}
        }
    Dim db As New Northwnd("c:\northwnd.mdf")
    Dim c As Customer = _
(From cust In db.Customers _
 Where cust.CustomerID = 19283).First
    c.Orders.Load()

    Dim orders = From ord In c.Orders _
                 Where ord.ShippedDate.Value.Year = 1998

    For Each nextOrder In orders
        ' Do something.
    Next

比较

这两项功能提供了强大的选项组合:大型集合采用以远程方式执行,小型集合或在需要完整集的情况下在本地执行。 您需要通过 IQueryable 进行远程执行,对于本地执行,则需要对内存中的 IEnumerable<T> 集合执行。 若要强制执行本地执行(即 IEnumerable<T>),请参阅将类型转换为泛型 IEnumerable

针对无序集的查询

对于实现 List<T> 的本地集合与提供对关系数据库中无序集执行的远程查询的集合,请注意它们之间的重要差异。 List<T> 方法(如使用索引值的那些方法)需要列表语义,列表语义通常无法通过针对无序集的远程查询获得。 因此,此类方法隐式加载 EntitySet<TEntity>,以允许本地执行。

请参阅