博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Entity Framework返回IEnumerable还是IQueryable?
阅读量:5295 次
发布时间:2019-06-14

本文共 3008 字,大约阅读时间需要 10 分钟。

在使用EF的过程中,我们常常使用repository模式,本文就在repository层的返回值是IEnumerable类型还是IQueryable进行探讨。

阅读目录:

一、什么是Repository模式?

二、IEnumerable还是IQueryable的区别

三、实际检验IEnumerable和IQueryable的效率差别

四、总结

一, 什么是Repository模式?

Repository是隔离在数据访问层和业务逻辑层之间的。它提供业务逻辑各种对象,使得业务逻辑代码不需要关心数据是如何存储和获取的。

下图,是MVC中使用Repository模式的模型图。Controller调用Repository来获取数据,而Repository调用EF来访问数据库。

Repository模式的好处是它为逻辑和数据访问解耦,使得它们之间没有互相依赖。Repository可以挑选不同的数据来源,不如MySql, WCF, Web Service等,都不会影响到业务逻辑的改动。

 

一段典型的Repository代码类似于:

public class DailyReportRepository : IDailyReportRepository{       private readonly Context _context;       public DailyReportRepository(Context context)       {           _context = context;       }       public IQueryable
GetAllDailyReports() { return from report in _context.dailyreports select report; } public IEnumerable
GetAllDailyReports(DateTime start, DateTime end) { var query = from report in GetAllDailyReports() where report.EntryDate >= start && report.EntryDate < end select report; return query; }}

二,IEnumerable还是IQueryable的区别

上面的代码中,函数的返回值一个是IEnumerable类型,一个是IQuerable类型,它们有什么不同呢? 那个更好?

IQueryable继承自IEnumerable,所以对于数据遍历来说,它们没有区别。

但是IQueryable的优势是它有表达式树,所有对于IQueryable的过滤,排序等操作,都会先缓存到表达式树中,只有当真正遍历发生的时候,才会将表达式树由IQueryProvider执行获取数据操作。

而使用IEnumerable,所有对于IEnumerable的过滤,排序等操作,都是在内存中发生的。也就是说数据已经从数据库中获取到了内存中,只是在内存中进行过滤和排序操作。

三,实际检验IEnumerable和IQueryable的效率差别

Repository的代码如下, 返回同样的数据,一个使用IEnumerable,一个使用IQueryable

public class StudentRepository : IStudentRepository{       private readonly SchoolContext _context;       public StudentRepository(SchoolContext context)       {           _context = context;       }       public IEnumerable
GetIEnumerableStudents() { return _context.Students; } public IQueryable
GetIQueryableStudents() { return _context.Students; } }

在Controller中分别调用, 从Repository中返回的数据中,取2条显示在页面上。

public class HomeController : Controller{       private readonly IStudentRepository _studentRepository;       public HomeController(IStudentRepository studentRepository)       {           _studentRepository = studentRepository;       }       public ActionResult Index()       {           //Repository使用IEnumerable返回结果           var students = _studentRepository.GetIEnumerableStudents().Take(2);           //Repository使用IQueryable返回结果           //var students = _studentRepository.GetIQueryableStudents().Take(2);           return View(students);       }}

呈现的页面如下:

 

但是通过MiniProfiler检测到的结果,使得真相水落石出。

前面一张是使用IEnumerable返回值的,后面一张是使用IQueryable返回值。

对比能够发现,使用IQueryable的查询,Take(2)的操作是通过Sql在数据库中完成的。

 

试想在数据较多的情况下或者操作比较复杂的情况下,IEnumerable的效率会比IQueryable低很多。

 

 

四,总结

结论应当非常明显,使用IQueryable作为Repository的返回值是我们最终的选择。

同时对于IQueryable有兴趣,不妨多深入研究。里面涉及的表达式树,是.net中的非常重要的概念。

下篇讨论,如何使用表达式树来增加Repository代码的灵活性。

转载于:https://www.cnblogs.com/JustRun1983/p/3261074.html

你可能感兴趣的文章
SRM 628 DIV2
查看>>
2018-2019-2 20165314『网络对抗技术』Exp5:MSF基础应用
查看>>
Python-S9-Day127-Scrapy爬虫框架2
查看>>
使用Chrome(PC)调试移动设备上的网页
查看>>
使用gitbash来链接mysql
查看>>
SecureCRT的使用方法和技巧(详细使用教程)
查看>>
右侧导航栏(动态添加数据到list)
查看>>
81、iOS本地推送与远程推送详解
查看>>
虚拟DOM
查看>>
uva 11468 Substring
查看>>
自建数据源(RSO2)、及数据源增强
查看>>
BootStrap2学习日记2--将固定布局换成响应式布局
查看>>
关于View控件中的Context选择
查看>>
2018icpc徐州OnlineA Hard to prepare
查看>>
Spark的启动进程详解
查看>>
使用命令创建数据库和表
查看>>
数据库的高级查询
查看>>
[YTU]_2443 ( C++习题 复数类--重载运算符3+)
查看>>
sdut_1189
查看>>
归并排序
查看>>