IQueryable 和 AsEnumerable():延迟执行与立即执行
IQueryable and AsEnumerable(): deferred execution vs immediate execution
能不能把AsEnumerable()
从GetCars
去掉,GetCars
还是延期执行?
public IEnumerable<Car> GetCars(string id)
{
IEnumerable<Car> cars = IDocumentClient.CreateDocumentQuery<Car>(link).AsEnumerable();
return cars.Where(r => r.Id == Id);
}
如下所示:
//GetCars2 is still deferred execution?
public IEnumerable<Car> GetCars2(string Id)
{
IOrderedQueryable<Car> cars = IDocumentClient.CreateDocumentQuery<Car>(link)
return cars.Where(r => r.Id == .Id);
}
更新
我希望首先在数据库中完成所有过滤,从而减少数据 returned。
此外,我在调用 GetCar()
后进行了更多过滤。使用 IEnumerable
允许延迟执行 GetCar()
内部和外部的过滤。
可以用IQueryable
代替吗?有什么好处?
SQL 查询(GetCar2 和 GetCar3)是否也考虑了 GetCars3 中的过滤?因此,这两种方法都减少了从数据库中编辑的数据 return?
public IEnumerable<Car> GetCars3(string Model )
{
return GetCars2(id).Where(r => r.Model == Model);
}
更新2
正如 mjwills
建议使用 IQueryable 作为 return 类型的 GetCarX()。但我不明白为什么。因为使用 IEnumerable<> 仍然有所有的好处。也就是说,过滤是在数据库端执行的,而不是 C#。如有错误请指正
Returning IEnumerable<T> vs. IQueryable<T>
LINQ 提供程序:
https://azure.microsoft.com/en-us/blog/azure-documentdb-s-linq-provider-just-got-better/
读取查询:
https://github.com/Azure/azure-cosmos-dotnet-v2/issues/58
SQL: https://docs.microsoft.com/en-gb/azure/cosmos-db/sql-query-getting-started#linq-to-documentdb-sql
更新 3
此问题与 AsEnumerable() 有关,它在定义 Where
的同一函数中使用,作为 don't it
.
的示例
它与之前的 post 有细微的差别,在 post.
上有更好的明确解释
因此,不应将此 post 标记为重复。
在您的两个示例中,它们将 运行 使用延迟执行 - 在迭代 IQueryable
或 IEnumerable
之前,它们不会将基础查询发送到服务器。
GetCars
和GetCars2
的区别仅在于当GetCars
的结果最终被其调用者枚举时,Where
谓词中的子句将是运行 在客户端——当 iterable 中的每个结果从服务器传来时,它将被评估并返回或丢弃;与 GetCars2
相比(如果 IQueryable
的特定实现支持它),Where
谓词将被考虑到发送到服务器的查询中。如果从 CreateDocumentQuery
返回的 IQueryable
的实现不支持方法链接来构造查询,那么它们将以相同的方式工作。但是在任何一种情况下,它们都使用延迟执行,因为在实际枚举方法的结果之前,不会向服务器发送任何内容。
响应添加到问题的更新 - 将 AsEnumerable()
视为门函数。它会切断将要与服务器通信的 IQueryable
与您在其后添加的任何其他 LINQ 类型方法之间的通信。 IQueryable
对 AsEnumerable
之后发生的事情视而不见。因此,如果您想使用方法链编写服务器端查询,请不要使用 AsEnumerable
.
中断链
能不能把AsEnumerable()
从GetCars
去掉,GetCars
还是延期执行?
public IEnumerable<Car> GetCars(string id)
{
IEnumerable<Car> cars = IDocumentClient.CreateDocumentQuery<Car>(link).AsEnumerable();
return cars.Where(r => r.Id == Id);
}
如下所示:
//GetCars2 is still deferred execution?
public IEnumerable<Car> GetCars2(string Id)
{
IOrderedQueryable<Car> cars = IDocumentClient.CreateDocumentQuery<Car>(link)
return cars.Where(r => r.Id == .Id);
}
更新
我希望首先在数据库中完成所有过滤,从而减少数据 returned。
此外,我在调用 GetCar()
后进行了更多过滤。使用 IEnumerable
允许延迟执行 GetCar()
内部和外部的过滤。
可以用IQueryable
代替吗?有什么好处?
SQL 查询(GetCar2 和 GetCar3)是否也考虑了 GetCars3 中的过滤?因此,这两种方法都减少了从数据库中编辑的数据 return?
public IEnumerable<Car> GetCars3(string Model )
{
return GetCars2(id).Where(r => r.Model == Model);
}
更新2
正如 mjwills
建议使用 IQueryable 作为 return 类型的 GetCarX()。但我不明白为什么。因为使用 IEnumerable<> 仍然有所有的好处。也就是说,过滤是在数据库端执行的,而不是 C#。如有错误请指正
Returning IEnumerable<T> vs. IQueryable<T>
LINQ 提供程序:
https://azure.microsoft.com/en-us/blog/azure-documentdb-s-linq-provider-just-got-better/
读取查询:
https://github.com/Azure/azure-cosmos-dotnet-v2/issues/58
SQL: https://docs.microsoft.com/en-gb/azure/cosmos-db/sql-query-getting-started#linq-to-documentdb-sql
更新 3
此问题与 AsEnumerable() 有关,它在定义 Where
的同一函数中使用,作为 don't it
.
它与之前的 post 有细微的差别,在 post.
上有更好的明确解释因此,不应将此 post 标记为重复。
在您的两个示例中,它们将 运行 使用延迟执行 - 在迭代 IQueryable
或 IEnumerable
之前,它们不会将基础查询发送到服务器。
GetCars
和GetCars2
的区别仅在于当GetCars
的结果最终被其调用者枚举时,Where
谓词中的子句将是运行 在客户端——当 iterable 中的每个结果从服务器传来时,它将被评估并返回或丢弃;与 GetCars2
相比(如果 IQueryable
的特定实现支持它),Where
谓词将被考虑到发送到服务器的查询中。如果从 CreateDocumentQuery
返回的 IQueryable
的实现不支持方法链接来构造查询,那么它们将以相同的方式工作。但是在任何一种情况下,它们都使用延迟执行,因为在实际枚举方法的结果之前,不会向服务器发送任何内容。
响应添加到问题的更新 - 将 AsEnumerable()
视为门函数。它会切断将要与服务器通信的 IQueryable
与您在其后添加的任何其他 LINQ 类型方法之间的通信。 IQueryable
对 AsEnumerable
之后发生的事情视而不见。因此,如果您想使用方法链编写服务器端查询,请不要使用 AsEnumerable
.