您好,登錄后才能下訂單哦!
這篇文章主要講解了“LINQ to SQL與NHibernate有什么不同”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“LINQ to SQL與NHibernate有什么不同”吧!
1 引言
研發與數據庫打交道的系統的時候,最過于繁瑣的莫過于沒有編程快感的使用ADO.NET對后臺數據庫進行操作,因為所有的數據庫連接、讀取、操作千篇一律,編程成為了體力活。
雖然我們可以設計自己的類作為數據庫訪問的持久層,但是每一個類都必須有不相同的SQL語句,這樣對于設計統一的數據庫讀寫類造成了很大的困難。
開發人員在這種情況下必須包辦窗體設計、方法設計、數據庫讀寫設計的過程,這樣加大了開發人員的負擔也使得項目的維護和后期開發變得難以進行。
2 .NET下的ORM解決方案
2.1 LINQ
2.1.1 LINQ簡介
作為微軟開發的查詢方案,LINQ 提供了一條更常規的途徑即給 .Net Framework 添加一些可以應用于所有信息源( all sources of information )的具有多種用途( general-purpose )的語法查詢特性( query facilities ),這是比向開發語言和運行時( runtime )添加一些關系數據( relational )特性或者類似 XML 特性( XML-specific )更好的方式。這些語法特性就叫做 .NET Language Integrated Query (LINQ) 。
如果覺得上面的解釋有點抽象,那么可以這樣理解,LINQ其實就是提供了一套查詢功能,可以實現任何數據源的查詢,此處數據源不單指數據庫或者XML文件,而是任何集合或者實體,比如我們接觸各種編程語言都需要用到的數組,現在不用遍歷數組元素來尋找需要的項,LINQ可以實現這方面的查詢。
LINQ查詢數組:
圖2.1 LINQ查詢數組
上面是最簡單的LINQ實現對數組的查詢,泛型類型var在LINQ查詢中提供了強大的委托類型支持,不管查詢集合中項的類型(無論是int,char還是string或者類),我們只用一個var就可以保存LINQ查詢到的結果。程序結果如下:
圖2.2 LINQ查詢數組程序結果
是不是很方便,LINQ的應用遠遠不這些,通過不同的映射方案,我們可以實現對數據庫(LINQ To SQL),對XML文件(LINQ To XML)的訪問。
2.1.2 LINQ簡介
表2.1 LINQ的操作符
操作符 | 說明 |
聚合 | |
Aggregate | 對序列執行一個自定義方法 |
Average | 計算數值序列的平均值 |
Count | 返回序列中的項目數(整數) |
LongCount | 返回序列中的項目數(長型) |
Min | 查找數字序列中的最小數 |
Max | 查找數字序列中的***數 |
Sum | 匯總序列中的數字 |
連接 | |
Concat | 將兩個序列連成一個序列 |
轉換 | |
Cast | 將序列中的元素轉換成指定類型 |
OfType | 篩選序列中指定類型的元素 |
ToArray | 從序列返回一個數組 |
ToDictionary | 從序列返回一個字典 |
ToList | 從序列返回一個列表 |
ToLookup | 從序列返回一個查詢 |
ToSequence | 返回一個 IEnumerable 序列 |
元素 | |
DefaultIfEmpty | 為空序列創建默認元素 |
ElementAt | 返回序列中指定索引的元素 |
ElementAtOrDefault | 返回序列中指定索引的元素,或者如果索引超出范圍,則返回默認值 |
First | 返回序列中的***個元素 |
FirstOrDefault | 返回序列中的***個元素,或者如果未找到元素,則返回默認值 |
Last | 返回序列中的***一個元素 |
LastOrDefault | 返回序列中的***一個元素,或者如果未找到元素,則返回默認值 |
Single | 返回序列中的單個元素 |
SingleOrDefault | 返回序列中的單個元素,或者如果未找到元素,則返回默認值 |
相等 | |
SequenceEqual | 比較兩個序列看其是否相等 |
生成 | |
Empty | 生成一個空序列 |
Range | 生成一個指定范圍的序列 |
Repeat | 通過將某個項目重復指定次數來生成一個序列 |
分組 | |
GroupBy | 按指定分組方法對序列中的項目進行分組 |
聯接 | |
GroupJoin | 通過歸組將兩個序列聯接在一起 |
Join | 將兩個序列從內部聯接起來 |
排序 | |
OrderBy | 以升序按值排列序列 |
OrderByDescending | 以降序按值排列序列 |
ThenBy | 升序排列已排序的序列 |
ThenByDescending | 降序排列已排序的序列 |
Reverse | 顛倒序列中項目的順序 |
分區 | |
Skip | 返回跳過指定數目項目的序列 |
SkipWhile | 返回跳過不滿足表達式項目的序列 |
Take | 返回具有指定數目項目的序列 |
TakeWhile | 返回具有滿足表達式項目的序列 |
投影 | |
Select | 創建部分序列的投影 |
SelectMany | 創建部分序列的一對多投影 |
限定符 | |
All | 確定序列中的所有項目是否滿足某個條件 |
Any | 確定序列中是否有任何項目滿足條件 |
Contains | 確定序列是否包含指定項目 |
限制 | |
Where | 篩選序列中的項目 |
設置 | |
Distinct | 返回無重復項目的序列 |
Except | 返回代表兩個序列差集的序列 |
Intersect | 返回代表兩個序列交集的序列 |
Union | 返回代表兩個序列交集的序列 |
Lambda 表達式
許多標準查詢操作符在對序列執行運算時都使用 Func 委托來處理單個元素。Lambda 表達式可與標準查詢操作符結合使用以代表委托。lambda 表達式是創建委托實現的簡略表達形式,并可用于匿名委托適用的所有場合。C# 和 Visual Basic® .NET 均支持 Lambda 表達式。但是,必須注意:由于 Visual Basic .NET 尚不支持匿名方法,Lambda 表達式可能僅包含一個語句。
上例中的的程序等同于下面
圖2.3 Lambda表達式的使用
2.2 NHibernate
說到NHibernate,就不得不提Hibernate,原因很簡單,Hibernate顧名思義就是Hibernate的.NET版本。
Hibernate是一個開放源代碼的對象關系映射框架,它對JDBC進行了非常輕量級的對象封裝,使得Java程序員可以隨心所欲的使用對象編程思維來操縱數據庫。 Hibernate可以應用在任何使用JDBC的場合,既可以在Java的客戶端程序使用,也可以在Servlet/JSP的Web應用中使用,***革命意義的是,Hibernate可以在應用EJB的J2EE架構中取代CMP,完成數據持久化的重任。
NHibernate作為Hibernate的.NET應用于Hibernate的實現完全相同,學習NHibernate完全可以直接學習Hibernate的資料。
事實上,雖然在Java數據庫映射領域Hibernate是使用最為廣泛的方案,但是在.NET中由于LINQ等映射方案(包括微軟下一代重量級的Entity Framework)的使用,NHibernate冷了許多。
NHibernate需要配置數據庫配置文件和類/表映射配置文件,所以使用NHibernate需要懂得XML文件的基礎知識,并且需要掌握比較復雜的XML文件配置節和相應的配置命令。
2.2.1 數據庫配置文件
NHibernate官方提供了配置文件的模板和實例可供我們參考。
圖2.4 NHibernate官方數據庫配置文件模板(對應了不同的數據庫)
上圖為數據庫配置文件。通常以“cfg.xml”作為后綴,一個示例的文件內容如下
圖2.5 數據庫配置文件示例
下面是一些在運行時可以改變NHibernate行為的其他配置。所有這些都是可選的,也有合理的默認值。
表2.2 NHibernate 配置屬性
屬性名 | 用途 |
hibernate.dialect | NHibernate方言(Dialect)的類名 - 可以讓NHibernate使用某些特定的數據庫平臺的特性 例如: full.classname.of.Dialect(如果方言創建在NHibernate中), 或者full.classname.of.Dialect, assembly (如果使用一個自定義的方言的實現,它不屬于NHibernate)。 |
hibernate.default_schema | 在生成的SQL中,scheml/tablespace的全限定名. 例如: SCHEMA_NAME |
hibernate.prepare_sql | 是否準備sql語句 例如: true | false |
hibernate.session_factory_name | SessionFactory被創建后將自動綁定這個名稱. 例如: some.name |
hibernate.use_outer_join | 允許使用外連接抓取。 例如:true | false |
hibernate.cache.provider_class | 指定一個自定義的CacheProvider緩存提供者的類名 例如: full.classname.of.CacheProvider(如果ICacheProvider創建在NHibernate中), 或full.classname.of.CacheProvider, assembly(如果使用一個自定義的ICacheProvider,它不屬于NHibernate)。 |
hibernate.query.substitutions | 把NHibernate查詢中的一些短語替換為SQL短語(比如說短語可能是函數或者字符)。 例如: hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC |
2.2.2 實體映射配置文件
NHibernate官方開源包中提供了實體映射配置文件的實例可供我們參考。
圖2.6 NHibernate開源包中提供的實體映射配置文件
與數據庫配置文件一樣實體映射配置文件也是XML文件(XML果然是很強大啊,微軟下一代應用程序開發技術WPF就是使用XML文件將C/S和B/S長期分居的二人統一到一個屋檐下),所不同的是實體映射配置文件后綴是“hbm.xml”。
圖2.7 實體映射配置文件
實體映射配置文件所要配置的信息一般為
Ø Schema
所有的XML映射都需要使用nhibernate-mapping-2.0 schema。目前的schema可以在NHibernate的資源路徑或者是NHibernate.dll的嵌入資源(Embedded Resource)中找到。NHibernate總是會優先使用嵌入在資源中的schema文件。
Ø hibernate-mapping
(1) | schema (可選): 數據庫schema名稱. |
(2) | default-cascade (可選 - 默認為 none): 默認的級聯風格. |
(3) | auto-import (可選 - 默認為 true): 指定是否我們可以在查詢語言中使用非全限定的類名(僅限于本映射文件中的類)。 |
(4) | default-access (可選 - 默認為 property): NHibernate訪問屬性值時的策略。 |
(5) | assembly (可選): 指定一個程序集,如果在映射文檔中沒有指定程序集,就使用這個程序集。 |
(6) | namespace (可選): 指定一個命名空間前綴,如果在映射文檔中沒有指定全限定名,就使用這個命名空間名。 |
Ø class
(1) | name: 持久化類(或者接口)的全限定名。 |
(2) | table: 對應的數據庫表名。 |
(3) | discriminator-value (可選 - 默認和類名一樣): 一個用于區分不同的子類的值,在多態行為時使用。 |
(4) | mutable (可選, 默認為 true): 表明該類的實例可變(不可變)。 |
(5) | schema (可選): 覆蓋在根 |
(6) | proxy (可選): 指定一個接口,在延遲裝載時作為代理使用。你可以在這里使用該類自己的名字。 |
(7) | dynamic-update (可選, 默認為 false): 指定用于UPDATE 的SQL將會在運行時動態生成,并且只更新那些改變過的字段。 |
(8) | dynamic-insert (可選, 默認為 false): 指定用于INSERT的 SQL 將會在運行時動態生成,并且只包含那些非空值字段。 |
(9) | polymorphism (可選, 默認為 implicit(隱式)): 界定是隱式還是顯式的使用查詢多態。 |
(10) | where (可選) 指定一個附加的SQL WHERE 條件,在抓取這個類的對象時會一直增加這個條件。 |
(11) | persister (可選): 指定一個定制的 IClassPersister. |
(12) | lazy(可選):假若設置 lazy="true",就是設置這個類自己的名字作為proxy接口的一種等價快捷形式。 |
Ø id
(1) | name (可選): 標識屬性的名字。 |
(2) | type (可選): 標識NHibernate類型的名字。 |
(3) | column (可選 - 默認為屬性名): 主鍵字段的名字。 |
(4) | unsaved-value (可選 - 默認為 null): 一個特定的標識屬性值,用來標志該實例是剛剛創建的,尚未保存。這可以把這種實例和從以前的session中裝載過(可能又做過修改--譯者注)但未再次持久化的實例區分開來。 |
(5) | access (可選 - 默認為 property): NHibernate用來訪問屬性值的策略。 |
除此之外我們可以通過其他途徑深入了解配置方面的知識,一個NHibernate項目,配置文件的錯誤往往導致錯誤的結果甚至使得程序無法運行。
感謝各位的閱讀,以上就是“LINQ to SQL與NHibernate有什么不同”的內容了,經過本文的學習后,相信大家對LINQ to SQL與NHibernate有什么不同這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。