1. 程式人生 > 其它 >ORM框架之EntityFramework

ORM框架之EntityFramework

1. 什麼是ORM

object relational mapping.png

ORM的全稱是Object Relational Mapping,即物件關係對映。它的實現思想就是將關係資料庫中表的資料對映成為物件,以物件的形式展現,這樣開發人員就可以把對資料庫的操作轉化為對這些物件的操作。因此它的目的是為了方便開發人員以面向物件的思想來實現對資料庫的操作。

2. DotNet下流行的ORM框架

  • NHibernate框架 來源於 Java 的 Hibernate 框架,採用XML檔案配置的方式。
  • Dapper

2. EF(ADO.NET Entity Framework)


微軟基於ADO.NET開發的ORM框架。EF首先生成sql,再呼叫ado.net訪問資料庫,最後使結果物件具體化.

EF 與 ADO.NET 的對比——EF優勢何在?

  • 業務邏輯和資料存取邏輯分離開來;
  • 新增操作 EF:一次連線,執行多條sql;SqlHelper裡使用一般寫法,連線又無法釋放,用using,會造成多次連線重置;
  • 更新操作: EF自動優化,只update set 有變化的欄位,EF也可以很方便地只 更新實體的指定屬性,產生的sql語句裡的set後的欄位會更少;
  • 智慧提示: 用linq, lamda表示式 有智慧提示,寫錯了編譯不過;寫sql語句 字串,調sqlhelper,sql語句寫錯一樣編譯通過;
  • 安全: 省去了防止sql注入的麻煩;
  • 資料庫變更: 使用EF,切換較方便;
  • 效率: 使用EF要比使用Ado.net開發效率高;
  • 可讀性: 程式碼的可讀性更高.

3. EF開發模式

EF開發模式.jpg

4. EF變更跟蹤
變更跟蹤指的是對緩存於EF Context中的實體的狀態的跟蹤與改變。所以瞭解變更跟蹤先看了解一下實體在EF Context中的幾種狀態。

EF Context 實體狀態.png

支援變更跟蹤最關鍵的一點是實體必須有主鍵。這樣實體才能被EF Context這個快取容器進行維護,並與資料庫中相應的條目實現一一對應來支援增刪改查。

變更跟蹤是預設啟用的,可以通過配置DbContext來關閉這個功能,如下程式碼:

context.Configuration.AutoDetectChangesEnabled = false;

注意:
一般來說不建議關閉變更跟蹤,除非是隻讀(只讀情況下用AsNoTracking獲取實體並自己做快取應該更好)
在關閉變更跟蹤的情況下,可以通過如下方法手動呼叫一次變更檢測(或者用下文將介紹的手動狀態改變),這樣後續的SavaChanges操作才能正確完成。
context.ChangeTracker.DetectChanges();
另外要注意的一點是,變更跟蹤只能在一個上下文內有效。即如果有兩個DbContext的例項,兩個DbContext各自作用域內的變更跟蹤是獨立的。

AsNoTracking
對於只讀操作,強烈建議使用AsNoTracking進行資料獲取,這樣省去了訪問EF Context的時間,會大大降低資料獲取的時間。
1

var student = context.Set<Student>().AsNoTracking().FirstOrDefault(s => s.StudentName ==
"王五"
);

5. EF資料載入:、
EF中和資料載入關係最密切的方法是IQueryable中名為Load的方法。Load方法執行資料查詢並把獲取的資料放到EF Context中。Load()和我們常用的ToList()很像,只是它不建立列表只是把資料快取到EF Context中。

var productGet = context.Set<Product>().Where(r=>r.Id == 1).ToList();
context.Set<Product>().Where(r=>r.Id == 1).Load();

1. 延遲載入
EF預設使用延遲載入獲取導航屬性關聯的資料

作為預設配置的延遲載入,需要滿足以下幾個條件:
context.Configuration.ProxyCreationEnabled = true;
context.Configuration.LazyLoadingEnabled = true;
導航屬性被標記為virtual

禁用延遲載入:

  • context.Configuration.LazyLoadingEnabled = false;
  • 把導航屬性virtual去掉可以禁用單個實體的延遲載入

2. 預載入

預載入就是使用Include方法並傳入需要同時獲取的關聯屬性

如果我們確實同時需要一個物件及其關聯資料,可以使用預載入以使它們通過一條SQL獲取(join 語句)。在之前測試關聯的程式碼中,我們已多次使用到預載入。

var product = context.Set<Product().Include(p=>p.Invoice).FirstOrDefault();
1人點贊 技術雜談 更多精彩內容,就在簡書APP "小禮物走一走,來簡書關注我" 還沒有人讚賞,支援一下 codeice邊做烘焙邊減肥的碼農,其實還是很快樂滴 總資產1 (約0.05元)共寫了1.9W字獲得17個贊共8個粉絲 全部評論0只看作者 按時間倒序 按時間正序

推薦閱讀更多精彩內容

    • Android - 收藏集 Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity... passiontim閱讀 154,578評論 23贊 678
    • Spring Cloud Spring Cloud為開發人員提供了快速構建分散式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智... 卡卡羅2017閱讀 118,046評論 14贊 132
codeice 總資產1 (約0.05元) React Native 生命週期 閱讀 243 React Native 觸控事件處理詳解 閱讀 224

推薦閱讀

PHP面試題大全 閱讀 158 UE4之UObject介紹 閱讀 42 SQLAlchemy 入門教程 閱讀 49 JDBC(一)如何使用JDBC連線資料庫 閱讀 243 SpringBoot的HttpMessageConverter使用(3)—Feign中的使用 閱讀 818

作者:codeice
連結:https://www.jianshu.com/p/85192ec7b479
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。