在我的查询中,我需要返回IEnumerable
,但我不知道此操作是否会使查询再次执行?
var data = Repository<Person>.Find().AsEnumerable();
Find()
会返回IQueryable
,因为IQueryable
会继承IEnumerable
。我怀疑AsEnumerable
是否重复执行。
我知道
var data = Repository<Person>.Find().ToList()
执行查询两次。一个用于Find()
,第二个用于Tolist()
答案 0 :(得分:20)
IQueryable 是IEnumerable。没有转换,因此没有任何工作。
当你明确地或通过调用GetEnumerator()
来呼叫foreach
时,工作就会发生。
另外,您确认Repository.Find().ToList()
两次调用SQL吗?这对我来说听起来不对。
答案 1 :(得分:11)
AsEnumerable
运算符应用于IQueryable之外, as
实际上并没有做任何事情。因此,您应用于对象的任何未来方法都将使用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.
答案 2 :(得分:1)
将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()不是聚合函数