关于C#:IEnumerable和 IQueryable辨析

IEnumerable<T> and IQueryable<T> clarification?

读完这个问题后,我需要清理一些东西。

1
2
3
4
5
6
7
IQueryable<Customer> custs = from c in db.Customers
where c.City =="<City>"
select c;

IEnumerable<Customer> custs = from c in db.Customers
where c.City =="<City>"
select c;

问题:

1)可以这样说吗:在第一个查询中,sqlserver正在运行整个操作,包括WHERE子句,并且只返回相关的行—而第二个查询执行SELECT *…并将所有行返回到C中,然后进行筛选?

2)如果我只是在记忆中有一个收藏呢?(var lstMyPerson = new List()号)

1
2
3
IQueryable<MyPerson> lst = from c in lstMyPerson
where c.City =="<City>"
select c;

VS

1
2
3
IEnumerable<MyPerson> custs = from c in lstMyPerson
where c.City =="<City>"
select c;

现在执行有什么区别?


1:不,不正确

由于您只将结果存储到IEnumerable中,但仍然具有生成结果的完全相同的表达式,因此它们都将在服务器上执行,并且只返回相关的行。

你会从中得到不同的行为:

1
2
3
IEnumerable<Customer> custs = from c in (IEnumerable<Customer>)db.Customers
    where c. City =="<City>"
    select c;

在这种情况下,您将强制使用db.Customers集合作为IEnumerable集合,枚举后将获取整个集合。

注意:

1
2
3
IEnumerable<Customer> x = from c in db.Customers
                          where c.City =="<City>"
                          select c;

与此不同:

1
2
3
IEnumerable<Customer> x = from c in db.Customers
                          select c;
IEnumerable<Customer> y = x.Where(c => c.City =="<City>");

在第一种情况下,where子句将是SQL的一部分,而在第二种情况下则不是。这就是为什么链接的问题/答案涉及差异,而您的代码没有。

还要注意,只有您编写的语句实际上不会在服务器上执行任何东西,因为它们实际上只存储一个懒惰的集合。如果继续枚举这些集合,那么此时相关的位将在服务器上执行。

2:List没有实现或者没有IQueryable的扩展方法,涉及的linq操作符也不会返回任何与IQueryable兼容的内容。

在这种情况下,第一个不会编译。