关于c#:将IQueryable转换为IEnumerable会再次执行查询吗?

does converting IQueryable to IEnumerable execute the query again?

在我的查询中,我需要返回IEnumerable,但是我不知道这个操作是否会使查询再次执行?

var data = Repository.Find().AsEnumerable();

Find()返回IQueryable,因为IQueryable继承IEnumerable。我怀疑江户十一〔六〕是否重复执行。

我知道var data = Repository.Find().ToList()执行两次查询。一个用于Find(),另一个用于Tolist()


iQueryable是IEnumerable。没有转化,因此没有任何形式的工作在进行。

当您显式地或通过调用foreach调用GetEnumerator()时,就会发生这种工作。

另外,您确认过Repository.Find().ToList()调用SQL两次吗?我听上去不太对劲。


AsEnumerable实际上除了将as运算符应用于您的iqueryable之外,什么都不做。因此,将来应用于对象的任何方法都将使用System.Linq.Enumerable扩展方法集,而不是System.Linq.Queryable方法集。

一切都是关于延期执行。在尝试枚举之前,不会对可查询源(可能是数据库)执行任何操作。

换言之:

1
2
3
var data=Repository.Find().AsEnumerable()
/* The query is only actually performed AFTER here */  
.ToList();

如果你的代码:

1
var data=Repository.Find().ToList();

执行两次查询,这是因为您在find()方法中做了一些不正确的事情,这绝对不应该是这种情况。

1
var data = Respository.Find();

应执行查询零次。

1
var result = data.ToList(); // THIS is what should execute the query.


把linq想象成一个"流",聚合函数就是一个"flush"。linq to db"流只能刷新一次。.aseNumerable(),.where(),……是准备查询的方法.tolist()、.first()、.max()是聚合但是如果你不调用聚合,那么你的LINQ结果就不会运行。它只有在被枚举时才开始工作。

前任

1
var result = users.Select(usr => usr.Name);

在这之前什么都不会发生

调用1个聚合

1
result.First()

或2个结果正在枚举

1
result.ToList().ForEach(...)

要回答您的问题-.find(),.aseNumerable()不是聚合函数