据我所知,当我在IQueryable
上使用LINQ扩展方法(使用lambda表达式语法),而该IQueryable
实际上是ObjectSet
的实例时,它们会被翻译成LINQ to SQL查询。我的意思是,命令
IQueryable<User> users = db.UserSet;
var users32YearsOld = users.Where(user => user.Age == 32);
与...完全相同
IQueryable<User> users = db.UserSet;
var users32YearsOld = from user in users where user.Age == 32 select user;
因此,在循环中枚举users32YearsOld
之类的操作之前,它们都没有命中数据库(希望我理解得正确)。
但是,如果我不将ObjectSet
掩码为IQueryable
而是掩码为IEnumerable
会发生什么? 所以如果它的类型是IEnumerable
?
IEnumerable<User> users = db.UserSet;
var users32YearsOld = users.Where(user => user.Age == 32);
这个操作会立即影响数据库吗(如果是,那么是在什么时候?是在第一行还是第二行?)还是像之前的命令一样,只有在枚举 users32YearsOld
时才会影响数据库?如果我使用以下命令是否会有任何区别?
IEnumerable<User> users = db.UserSet;
var users32YearsOld = from user in users where user.Age == 32 select user;
谢谢你
IEnumerable
上调用Where(u => u.Age == 32)
时,它不会进行枚举吗?这是如何实现的(我可以想象它的工作方式类似于IQueryable
,但知道比猜测更好)? - RastoIEnumerable
上调用Where(u => u.Age == 32)
时,它不会枚举,而只是创建一个新的可枚举对象,该对象具有对原始对象的引用和一些“where”过滤器附加?或者它是如何工作的?也许这应该是另一个问题... - RastoIEnumerable
和IQueryable
都具有延迟执行)。这就是为什么在测试之前我对我的答案产生了怀疑的原因。 - Ladislav MrnkaIQueryable
变量上进行.Where()
或其他 Linq 调用时,表示表达式的对象树将被添加到实现IQueryable
的对象中。IQueryable
实现了IEnumerable
,因此同样的事情也会发生在这里。当你实际枚举表达式时,表达式树将被评估/转换为 SQL 并传递到数据库服务器。 - Tony Vitabile