将IQueryable转换为IEnumerable会再次执行查询吗?
在我的查询中,我需要返回IEnumerable
但我不知道这个动作是否使查询再次执行?
var data = Repository.Find().AsEnumerable();
Find()
返回IQueryable
,因为IQueryable
inheritance了IEnumerable
。 我怀疑AsEnumerable
会重复执行。
我知道var data = Repository.Find().ToList()
执行两次查询。 一个用于Find()
,第二个用于Tolist()
IQueryable 是一个IEnumerable。 没有转换,因此没有任何工作。
当您通过显式或通过调用foreach
调用GetEnumerator()
,工作就会发生。
另外,您确认Repository.Find().ToList()
调用SQL两次吗? 这对我来说听起来不对。
除了将as
运算符应用于IQueryable之外, AsEnumerable
实际上并没有做任何事情。 因此,您应用于对象的任何未来方法都将使用System.Linq.Enumerable扩展方法集,而不是System.Linq.Queryable方法。
这都是关于延期执行的。 在您尝试枚举之前,没有任何东西会对您的可查询源(可能是数据库)执行任何操作。
换一种说法:
var data=Repository.Find().AsEnumerable() /* The query is only actually performed AFTER here */ .ToList();
如果你的代码:
var data=Repository.Find().ToList();
执行查询两次,这是因为你在Find()方法中做了一些不正确的事情,绝对不应该这样。
var data = Respository.Find();
应执行查询ZERO次。
var result = data.ToList(); // THIS is what should execute the query.
将linq视为“流”并且聚合函数是“Flush”。 “linq to db”流只能刷新一次。 .AsEnumerable(),. Where(),….是一种准备查询的方法.ToList(),.First(),. Max()是一个聚合但是如果你不调用聚合,那么你的linq结果就不会运行。 它只有在枚举时才开始工作。
前
var result = users.Select(usr => usr.Name);
直到,这里什么都不会发生
调用1个聚合
result.First()
或2个结果被列举
result.ToList().ForEach(...)
回答你的问题 – .Find(),. AsEnumerable()不是一个聚合函数