刚学习EF框架发现查询数据库的返回值类型有些特别、不一样。
Linq和Where的返回值类型都为IQueryable和IEnumerable。
那他们的区别在哪里呢?
开始百度
于是就找到了这遍帖子。
https://blog.csdn.net/ydm19891101/article/details/50969323
由于原帖篇幅较长,这里做个简单总结。
Queryable类:
private void Form1_Load(object sender, EventArgs e)
{
using (DemoContext context = new DemoContext())
{
var customer = context.cunstomer.Where(c => c.Name == "牡丹");
foreach (var item in customer)
{
Console.Write(item.Id.ToString());
}
}
}
使用sql server profiler监视工具(sql server自带的)
在VS中断点运行上面代码
1、逐过程运行(F10)
运行到 foreach 这时候var customer = context.cunstomer.Where(c => c.Name == “牡丹”);已经运行完成了,但监视器依然没有动静可见他这是还没有进数据库,继续逐过程。
这时候监视器有反应了,已经监视到查询语句了。 context.cunstomer.Where()只有在调用customer(数据)时才真正进入数据库执行查询。
Enumable类:
private void Form1_Load(object sender, EventArgs e)
{
using (DemoContext context = new DemoContext())
{
var customer = context.cunstomer.Where(c => c.Name == "牡丹").AsEnumerable();
foreach (var item in customer)
{
Console.Write(item.Id.ToString());
}
}
}
同样是打开监视工具,添加断点,运行程序
单步调试,继续运行
关于上面的两个测试总结如下。
(1)所有对于IEnumerable的过滤,排序等操作,都是在内存中发生的。也就是说数据已经从数据库中获取到了内存中,只是在内存中进行过滤和排序操作。
(2)所有对于IQueryable的过滤,排序等操作,只有在数据真正用到的时候才会到数据库中查询。这也是Linq的延迟加载核心所在。
但是我认为这两个测试并没有明显体现出IQueryable和IEnumerable的区别。
IQueryable和IEnumerable的区别
下面是我翻遍整个百度收集到的资料自己做了个测试
控制台程序:
分页查询
EFDBEntities eFDB = new EFDBEntities();
IQueryable<Students> list = (from c in eFDB.Students orderby c.StudentId select c).Skip<Students>(3).Take<Students>(3);
IEnumerable<Students> list_1 = (from c in eFDB.Students orderby c.StudentId select c).AsEnumerable<Students>().Skip<Students>(3).Take<Students>(3);
foreach (var aa in list)
{
Console.WriteLine(aa.StudentName);
}
foreach (var aa in list_1)
{
Console.WriteLine(aa.StudentName);
}
IQueryable类返回 查询:
上面SQL语句执行后效果(IQueryable):
查询出来的是经过条件筛选过后的数据。
IEnumerable类返回 查询
上面SQL语句执行后效果(IEnumerable):
查询出来的是整张表,并没有按照条件去筛选。(全部查出在内存中筛选)
从这4张图可以看出
IQueryable 是在把筛选的条件都转为SQL语句在数据库查询时直接筛选。
IEnumerable 是在数据库中把整张表查出来保存在内存中,再进行筛选。