1. 程式人生 > >Entity Framework返回IEnumerable還是IQueryable?

Entity Framework返回IEnumerable還是IQueryable?

在使用EF的過程中,我們常常使用repository模式,本文就在repository層的返回值是IEnumerable型別還是IQueryable進行探討。

閱讀目錄:

一、什麼是Repository模式?

二、IEnumerable還是IQueryable的區別

三、實際檢驗IEnumerable和IQueryable的效率差別

四、總結

一, 什麼是Repository模式?

Repository是隔離在資料訪問層和業務邏輯層之間的。它提供業務邏輯各種物件,使得業務邏輯程式碼不需要關心資料是如何儲存和獲取的。

下圖,是MVC中使用Repository模式的模型圖。Controller呼叫Repository來獲取資料,而Repository呼叫EF來訪問資料庫。
Repository模式的好處是它為邏輯和資料訪問解耦,使得它們之間沒有互相依賴。Repository可以挑選不同的資料來源,不如MySql, WCF, Web Service等,都不會影響到業務邏輯的改動。

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

一段典型的Repository程式碼類似於:

public class DailyReportRepository : IDailyReportRepository
{
       private readonly Context _context;

       public DailyReportRepository(Context context)
       {
           _context = context;
       }

       public IQueryable<dailyreport> GetAllDailyReports()
       {
           
return from 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

public class StudentRepository : IStudentRepository
{
       private readonly 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條顯示在頁面上。

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);
       }
}

呈現的頁面如下:

t2

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

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

對比能夠發現,使用IQueryable的查詢,Take(2)的操作是通過Sql在資料庫中完成的。

試想在資料較多的情況下或者操作比較複雜的情況下,IEnumerable的效率會比IQueryable低很多。

t1

t3

四,總結

結論應當非常明顯,使用IQueryable作為Repository的返回值是我們最終的選擇。
同時對於IQueryable有興趣,不妨多深入研究。裡面涉及的表示式樹,是.net中的非常重要的概念。

下篇討論,如何使用表示式樹來增加Repository程式碼的靈活性。

相關推薦

Entity Framework返回IEnumerable還是IQueryable?

在使用EF的過程中,我們常常使用repository模式,本文就在repository層的返回值是IEnumerable型別還是IQueryable進行探討。 閱讀目錄: 一、什麼是Repository模式? 二、IEnumerable還是IQueryable的區別 三、實際檢驗IEnumerab

Entity Framework DbSet<T>之Include方法與IQueryable<T>擴展方法Include的使用

work exp 這樣的 tin mapping oid role .cn expr Entity Framework使用Code First方式時,實體之間已經配置好關系,根據實際情況某些情況下需要同時獲取導航屬性,比如獲取商品的同時需要獲取分類屬性(導航屬性),或者基於

C# Entity Framework中的IQueryable和IQueryProvider詳解

oid display provide 分析 當前 負責 nbsp enum share 前言 相信大家對 Entity Framework 一定不陌生,我相信其中Linq To Sql是其最大的亮點之一,但是我們一直使用到現在卻不曾明白內部是如何實現的,今天我們

Entity Framework 的事務 DbTransaction

public null public static void Transaction() { myitEntities entity = null; DbTransaction tran = null; try { entity = new myitEntitie

如何讓Entity Framework Db Frist模式下的Entity繼承關系?

clas use hide closed 相關 ase 創建 color 修改 1、使用DB Frist模式創建實體數據模型 Db Frist創建實體數據模型(創建edmx並不是重點,各位隨意即可),此處取名ZeroCodeDB,所得文件如圖所示; 其中紅框中的文件(Z

Entity Framework的啟動速度優化

映射 自帶 1-1 man 同時 找到 優化 http target 剛開始的時候沒有太在意,但是隨著系統的發布,這種初次請求,或者閑置若幹時間後第一次請求的漫長等待使得App的體驗很差,很多時候App加載好半天數據都沒過來。如果前端沒處理好,還會導致App的假死。所以就花

利用Mocking Framework 單元測試Entity Framework

dom class exp detached 異步 dbr cnblogs kde num 一、前言   在實際編寫程序時,往往需要與數據庫打交道,在單元測試中直接使用數據庫又顯得太重,如果可以方便的編寫一些測試數據,這樣更易於檢測功能。如何模擬數據庫行為便是本篇的主題。微

Entity Framework Code First (三)Data Annotations

pos .cn ase image 希望 編程 create str length Entity Framework Code First 利用一種被稱為約定(Conventions)優於配置(Configuration)的編程模式允許你使用自己的 domain class

Asp.Net.Identity認證不依賴Entity Framework實現方式

aps 新建 create exc spn sharp 個數 blank aspnet Asp.Net.Identity為何物請自行搜索,也可轉向此文章http://www.cnblogs.com/shanyou/p/3918178.html 本來微軟已經幫我們將授權、認證

LINQ TO SQL和Entity Framework 的關系 你了解多少?

mode 最小 -m 發的 開發 content 內容 語言 account 1. LINQ TO SQL 和EF 特點: LINQ TO SQL和Entity Framework都是一種包含LINQ功能的ORM 也就是所謂的關系對象的映射。其中包括的有DBFrist

Entity Framework

引用 .aspx foreign for 必須 ons .com work key https://msdn.microsoft.com/en-us/library/jj679962(v=vs.113).aspx 1.引用Entity Framework 2.Data A

Entity Framework Code First to a New Database

con str open use lin log efi install mic 1. Create the Application To keep things simple we’re going to build a basic console applicati

Entity Framework Code First to an Existing Database

post red arc for ram .com als opened and 1. Create an Existing Database CREATE TABLE [dbo].[Blogs] ( [BlogId] INT IDENTITY (1, 1)

Entity Framework 添加、附加、和實體狀態

鍵值 name 五個 能夠 att first 通過 數據集 attach   這篇文章將會覆蓋如何新增和附加實體到上下文以及在 SaveChanges 中Entity Framework 如何處理它們。 Entity Framework 會在實體與上下文連接時追蹤它們的

Entity Framework學習筆記——EF簡介(一篇文章告訴你什麽是EF)

比較 編程 ast 定義 .aspx b2c 文件創建 發送 ase Entity Framework是以ADO.NET為基礎,面向數據的“實體框架”。以下簡稱EF。 它利用了抽象化數據結構的方式,將每個數據庫對象都轉換成應用程序對象 (entity),

Entity Framework學習筆記——edmx文件

tinc metadata glob 兩個類 color empty 完成 文件中 文件的 上文簡單介紹了一下Entity FrameWork,這裏說一下EF的核心——edmx文件。 在VisualStudio中建立edmx文件(此例環境為Visual

MVC5 Entity Framework學習之實現主要的CRUD功能

之前 顯式 sea variable host ive spl url 轉載 在上一篇文章中,我們使用Entity Framework 和SQL Server LocalDB創建了一個MVC應用程序,並使用它來存儲和顯示數據。在這篇文章中,你將對由 MVC框架自己主

Entity framework 加載多層相關實體數據

ide date .com microsoft image sql art mic when Entity framework有3種加載數據的方式:懶漢式(Lazy loading),餓漢式(Eager loading),顯示加載(Explicit loading)。3種加

Entity Framework 基礎

sea port runt ext2 byte start 4.5 byte[] 生命 一、什麽是Entity Framework 微軟官方提供的ORM工具,ORM讓開發人員節省數據庫訪問的代碼時間,將更多的時間放到業務邏輯層代碼上。EF提供變更跟蹤、唯一性約束、惰

Entity Framework(三):使用特性(數據註解)創建表結構

int32 概念 ann 應該 etime max 繼承 兩個 width 一、理解Code First及其約定和配置   傳統設計應用的方式都是由下而上的,即我們習慣優先考慮數據庫,然後使用這個以數據為中心的方法在數據之上構建應用程序。這種方法非常適合於數據密集的應用或者