C# IQueryable和AsEnumerable():延迟执行与立即执行
是否可以从C# IQueryable和AsEnumerable():延迟执行与立即执行,c#,azure-cosmosdb,azure-cosmosdb-sqlapi,C#,Azure Cosmosdb,Azure Cosmosdb Sqlapi,是否可以从GetCars中删除AsEnumerable(),并且GetCars仍然是延迟执行 public IEnumerable<Car> GetCars(string id) { IEnumerable<Car> cars = IDocumentClient.CreateDocumentQuery<Car>(link).AsEnumerable(); return cars.Where(r => r.Id == Id); } 更新2
GetCars
中删除AsEnumerable()
,并且GetCars
仍然是延迟执行
public IEnumerable<Car> GetCars(string id)
{
IEnumerable<Car> cars = IDocumentClient.CreateDocumentQuery<Car>(link).AsEnumerable();
return cars.Where(r => r.Id == Id);
}
更新2
正如mjwills
建议使用IQueryable作为GetCarX()的返回类型。但我不明白为什么。因为使用IEnumerable仍然有所有的好处。也就是说,文件归档是在数据库端执行的,而不是在C#上执行的。如果我错了,请纠正我
LINQ提供程序:
阅读查询:
SQL:
更新3
这个问题与AsEnumerable()有关,它在定义了的同一个函数中使用,作为不要的一个例子
它与以前的文章有一个细微的区别,在这篇文章中有更明确的解释
因此,这篇文章不应该被标记为重复。在您的两个示例中,它们都将使用延迟执行运行-在迭代
IQueryable
或IEnumerable
之前,它们不会将基础查询发送到服务器
GetCars
和GetCars2
之间的区别在于,当调用方最终枚举GetCars
的结果时,Where
谓词中的子句将在客户端上运行,因为iterable中的每个结果都是从服务器传下来的,将进行评估并退回或丢弃;与在GetCars2
中(如果IQueryable
的具体实现支持它)相比,Where
谓词将被分解到发送到服务器的查询中。如果从CreateDocumentQuery
返回的IQueryable
的实现不支持方法链接来构造查询,那么它们将以相同的方式工作。但在这两种情况下,它们都使用延迟执行,在方法的结果实际枚举之前,不会向服务器发送任何内容
响应添加到问题中的更新-将
AsEnumerable()
视为门函数。它会切断将要与服务器对话的IQueryable
与之后添加的任何其他LINQ类型方法之间的通信。IQueryable
对AsEnumerable
之后发生的事情视而不见。因此,如果您想使用方法链接组成服务器端查询,请不要使用AsEnumerable
中断链接添加AsEnumerable
不会使其成为“立即执行”。这只是意味着后续的过滤等将是客户端(即在C#中)。一般来说,如果它是IQueryable
,那么请尽量长时间地保留它IQueryable
。但是CreateDocumentQuery(link)
在调用'AsEnumerable()'之前不会发出查询。我想所有的过滤都要先在数据库中完成,因此,减少返回的数据。使用AsEnumerable
几乎肯定不会给您带来任何有用的东西。我建议使用IQueryable
。如果GetCars
返回一个IQueryable
,则可以进行进一步的筛选(可以在服务器端进行,而不是在C#中进行筛选(如果使用AsEnumerable
则在下载所有记录后将进行C#筛选)。请参阅更新3以重新打开帖子。谢谢。帮助
//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);
}
public IEnumerable<Car> GetCars3(string Model )
{
return GetCars2(id).Where(r => r.Model == Model);
}