Entity Framework返回IEnumerable仍是IQueryable?何種效率高?

在使用EF的過程當中,咱們經常使用repository模式,本文就在repository層的返回值是IEnumerable類型仍是IQueryable進行探討。html

閱讀目錄:數據庫

1、什麼是Repository模式?緩存

2、IEnumerable仍是IQueryable的區別ide

3、實際檢驗IEnumerable和IQueryable的效率差異函數

4、總結url

一, 什麼是Repository模式?

Repository是隔離在數據訪問層和業務邏輯層之間的。它提供業務邏輯各類對象,使得業務邏輯代碼不須要關心數據是如何存儲和獲取的。spa


下圖,是MVC中使用Repository模式的模型圖。Controller調用Repository來獲取數據,而Repository調用EF來訪問數據庫。.net

Repository模式的好處是它爲邏輯和數據訪問解耦,使得它們之間沒有互相依賴。Repository能夠挑選不一樣的數據來源,不如MySql, WCF, Web Service等,都不會影響到業務邏輯的改動。3d

CRUD-using-the-Repository-Pattern-in-MVC-1

一段典型的Repository代碼相似於:code

複製代碼
publicclass DailyReportRepository : IDailyReportRepository{       privatereadonly Context _context;       public DailyReportRepository(Context context)       {           _context = context;       }       public IQueryable<dailyreport> GetAllDailyReports()       {           returnfrom report in _context.dailyreports                  select report;       }      public IEnumerable<dailyreport> 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

複製代碼
publicclass StudentRepository : IStudentRepository{       privatereadonly SchoolContext _context;       public StudentRepository(SchoolContext context)       {           _context = context;       }       public IEnumerable<Student> GetIEnumerableStudents()       {           return _context.Students;       }       public IQueryable<Student> GetIQueryableStudents()       {           return _context.Students;       }
}
複製代碼

在Controller中分別調用, 從Repository中返回的數據中,取2條顯示在頁面上。

複製代碼
publicclass HomeController : Controller{       privatereadonly 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);       }}
複製代碼

呈現的頁面以下:

t2


可是經過MiniProfiler檢測到的結果,使得真相水落石出。

前面一張是使用IEnumerable返回值的,後面一張是使用IQueryable返回值。

對比可以發現,使用IQueryable的查詢,Take(2)的操做是經過Sql在數據庫中完成的。


試想在數據較多的狀況下或者操做比較複雜的狀況下,IEnumerable的效率會比IQueryable低不少。

t1


t3


四,總結

結論應當很是明顯,使用IQueryable做爲Repository的返回值是咱們最終的選擇。

同時對於IQueryable有興趣,不妨多深刻研究。裏面涉及的表達式樹,是.net中的很是重要的概念。





轉載:http://www.cnblogs.com/JustRun1983/archive/2013/08/15/3261074.html

相關文章
相關標籤/搜索