IQueryable和AsEnumerable(): 延迟执行与即时执行
IQueryable和AsEnumerable(): 延迟执行与即时执行
这个问题已经在这里有答案了:
IQueryable和IEnumerable之间的区别是什么?
如果从GetCars
中移除AsEnumerable()
,GetCars
是否仍然是延迟执行的?
public IEnumerable GetCars(string id) { IEnumerable cars = IDocumentClient.CreateDocumentQuery(link).AsEnumerable(); return cars.Where(r => r.Id == Id); }
就像下面这样:
//GetCars2 is still deferred execution? public IEnumerable GetCars2(string Id) { IOrderedQueryable cars = IDocumentClient.CreateDocumentQuery(link) return cars.Where(r => r.Id == .Id); }
更新
我希望所有的过滤都是先在数据库中完成的,从而减少返回的数据量。
此外,在调用GetCar()
之后,我还有更多的过滤。使用IEnumerable
允许内部和外部过滤进行延迟执行。
IQueryable
能否替代?好处是什么?
GetCars3
中的过滤是否也考虑在SQL查询中(GetCar2和GetCar3都是)?因此,这两种方法都可以减少从数据库返回的数据?
public IEnumerable GetCars3(string Model ) { return GetCars2(id).Where(r => r.Model == Model); }
更新2
正如mjwills
建议使用 IQueryable 作为 GetCarX() 的返回类型。但我不明白为什么。因为使用 IEnumerable<> 仍然具有所有的好处。也就是说,过滤是在数据库端执行的,而不是在 C# 中。如果我错了,请纠正我。
LINQ 提供程序:
https://azure.microsoft.com/en-us/blog/azure-documentdb-s-linq-provider-just-got-better/
读取查询:
如何使用 Linq 构建 IQueryable 查询,当我只需要计数而不需要读取 Document-Db 数据库中的所有文档?
https://github.com/Azure/azure-cosmos-dotnet-v2/issues/58
如何使用 Linq 构建 IQueryable 查询,当我只需要计数而不需要读取 Document-Db 数据库中的所有文档?
SQL:https://learn.microsoft.com/en-gb/azure/cosmos-db/sql-query-getting-started#linq-to-documentdb-sql
更新3
这个问题涉及到AsEnumerable(),它在定义了Where
的同一个函数中使用,作为don\'t it
的例子。
与之前的帖子有微妙的不同,这在本帖中更好地得到了明确解释。
因此,本帖不应被标记为重复。
在你提出的这两个例子中,它们都使用了延迟执行——直到迭代 IQueryable
或 IEnumerable
,才会将基础查询发送到服务器。\n\nGetCars
和 GetCars2
之间的区别仅在于,当 GetCars
的结果最终被调用者枚举时,Where
谓词中的子句将在客户端上运行——当可枚举对象中的每个结果从服务器传递并经过时,它将被评估并返回或丢弃。相比之下,在 GetCars2
中(如果特定的 IQueryable
实现支持),Where
谓词将被合并到发送到服务器的查询中。如果从 CreateDocumentQuery
返回的 IQueryable
实现不支持使用方法链接构造查询,则它们都将以相同的方式工作。但无论哪种情况,它们都使用延迟执行,只有在方法的结果实际被枚举时,才会将任何内容发送到服务器。\n\n回应问题中添加的更新——将 AsEnumerable()
视为一个门函数。它切断了将要与服务器通信的 IQueryable
和在其后面添加的任何其他 LINQ 类型方法之间的通信。 IQueryable
对在 AsEnumerable
之后发生的情况是不知道的。因此,如果您想使用方法链接组合服务器端查询,不要用 AsEnumerable
中断链条。