天天看點

Grove——.NET中的ORM實作

釋出日期: 6/30/2005 | 更新日期: 6/30/2005

作者:林學鵬

ORM的全稱是Object Relational Mapping,即對象關系映射。它的實質就是将關系資料(庫)中的業務資料用對象的形式表示出來,并通過面向對象(Object-Oriented)的方式将這些對象組織起來,實作系統業務邏輯的過程。在ORM過程中最重要的概念是映射(Mapping),通過這種映射可以使業務對象與資料庫分離。從面向對象來說,資料庫不應該和業務邏輯綁定到一起,ORM則起到這樣的分離作用,使資料庫層透明,開發人員真正的面向對象。圖 1簡單說明了ORM在多層系統架構中的這個作用。

圖1:ORM在多層系統架構中的作用

目前大多數項目或産品都使用關系型資料庫實作業務資料的存儲,這樣在開發過程中,常常有一些業務邏輯需要直接用寫SQL語句實作,但這樣開發的結果是:遍地布滿SQL語句。這些高藕合的SQL語句給系統的改造和更新帶來很多無法預計的障礙。為了提高項目的靈活性,特别是快速開發,ORM是一個不錯的選擇。舉個簡單的例子:在使用ORM的系統中,當資料庫模型改變時,不再需要理會邏輯代碼和SQL語句中涉及到該模型的所有改動,隻需要将該模型映射的對象稍作改動,甚至不做改動就可以滿足要求。

<a href="http://www.microsoft.com/china/MSDN/library/netFramework/netframework/Grove.mspx#EEB"></a>

<a href="http://www.microsoft.com/china/MSDN/library/netFramework/netframework/Grove.mspx#EEB">一、ORM的工具實作:Grove</a>

<a href="http://www.microsoft.com/china/MSDN/library/netFramework/netframework/Grove.mspx#EOC"></a>

<a href="http://www.microsoft.com/china/MSDN/library/netFramework/netframework/Grove.mspx#EOC">二、Grove在開發中的實際應用</a>

<a href="http://www.microsoft.com/china/MSDN/library/netFramework/netframework/Grove.mspx#E2AAC"></a>

<a href="http://www.microsoft.com/china/MSDN/library/netFramework/netframework/Grove.mspx#E2AAC">三、總結</a>

<a></a>

優秀的ORM工具不僅可以幫助我們很好的了解對象及對象的關系,而且工具本身會幫助我們維護這些關系。基于這個理念,我設計了基于.NET的ORM工具——Grove ORM Development Toolkit。

Grove ORM Development Toolkit包含Grove和Toolkit兩部分内容。Grove為ORM提供對象持久、關系對象查詢、簡單事務處理、簡單異常管理等功能。資料持久包括一些對象的Insert、Delete、Update、Retrieve等功能,關系對象查詢則提供一些基于對象的複雜關系查詢,包括對應到資料庫功能的子查詢、關聯查詢(JOIN)、函數支援(count、avg、max、min)、聚合等。Toolkit是基于VS.NET 2002/2003的VSIP開發的外接程式,職責是幫助開發人員快速映射關系資料庫中的業務模型到符合Grove要求的映射實體類,以及映射資料庫中複雜關系查詢到Grove要求的關系映射實體,暫時隻提供C#支援。圖 2是Grove内部類實作關系圖。

圖 2: Grove内部類實作關系圖

在ORM實作的前期工作中,為了實作屏蔽各種資料庫之間的操作差異,我們需要定義資料操作公有接口,封裝基本的資料庫Insert,Update,Delete,Query等操作。

再定義一個資料庫操作工廠類,實作各種不同類型資料的适配。

然後實作各種資料庫的操作類,以SQLServer為例。

完成後,就是ORM主角——實體(Entity)的實作。ORM中實體的定義可以通過實體類自身包含資料模型中繼資料的方式實作,也可以通過定義XML的元描述實作。下面講述了通過實體類自身映射的實作。

實體(Entity)是實際業務資料的載體,包含業務資料模型的元描述,可以直接由資料庫中的某張表或視圖生成,也可以根據需要手工建立。.NET中提供了System.Attribute,該類包含通路和測試自定義屬性的簡便方法。.NET Framework預定義了一些屬性類型并使用它們控制運作時行為。我們可以通過繼承System.Attribute基類自定義用于描述實體對象映射時所需要的資料模型中繼資料,包括表名,字段名,字段長度,字段類型等一些常用的資料。

AttributeUsage用來表示該自定義屬性可以被綁定在什麼樣的對象上,這裡表示應用在Class或者Struct之上。

抽象一些具有相同特征的屬性,使之成為自定義屬性的基類。

定義一般字段所需要的自定義屬性類。

定義關鍵字字段所需的自定義屬性類。

定義外鍵字段所需要的自定義屬性類。

在以上自定義屬性類完成後,我們需要一個用于通路實體在運作期綁定的自定義屬性及屬性資料的一個Help類。

實體定義完成後,我們需要根據實體類中綁定的自定義屬性構造出運作期需要的SQL語句,為了收集實體類定義中的資料結構描述,我們需要定義一個類來說明實體在運作期所引用到的所有關于資料持久的資訊,包括關鍵字字段,外鍵字段,一般字段等。

同時需要一個字段中繼資料描述類,描述字段在資料庫中的名稱,大小,是否可為空,列類型等資訊。

以上條件具備後,我們需要定義一個解析類,負責轉換資料的程式類型到資料庫字段類型,并且構造出Insert,Update,Delete,Query等操作所需要的SQL語句。

将上面的操作組合起來就是實體類對象操作員。

實作新增一個記錄到資料庫中,就是建立了一個新的實體對象,并交由對象操作員進行持久化。

這裡的SQLCommand對象封裝了SQL指令處理時所需要的一些值,包含SQL語句,指令參數(Parameter)等。

安裝Grove Kit要求Visual Studio 2003 及.NET Framework 1.1支援。從Grove網站下載下傳安裝包之後,解壓縮GroveKit.zip,執行安裝。

在GroveKit安裝結束後,打開VS.NET,在VS.NET的啟動畫面上,您會看到Grove Develop Kit的标志,表示GroveKit已被正确安裝。

<b>2.1</b><b>生成映射實體類</b>

本文将以C# 項目為例解釋Grove在開發中的具體應用。項目名WebApp1,作業系統 Windows 2000,資料庫SQL Server 2000,資料庫執行個體名:WebApp1,表結構定義如下:

表名

字段

Customers

CustomerID int(4) PK

CustomerName varchar(50)

CustomerDesc varchar(200)

Status tinyint

Addresses

AddressID int(4) PK

CustomerID int(4) FK

Address varchar(200)

1.

在VS.NET中,打開“檔案-&gt;建立-&gt;項目”,在Visual C#項目選擇ASP.NET WEB應用程式,确定後生成WebApp1項目,在項目中添加對Grove.dll的引用,Grove.dll位于GroveKit的安裝路徑下,您也可以通過.NET Configuration将Grove添加到程式集緩存中。

2.

在VS.NET中,打開“工具-&gt;Grove Tool Kit”,在GroveToolKit中設定資料庫連接配接屬性,并儲存。

圖3 設定資料庫連接配接串

3.

配置目前Web項目的web.config(在&lt;/configuration&gt;之前加入以下配置)

4.

4)在VS.NET解決方案資料總管中選中Entities,并在GroveToolKit中選擇表名,點選GroveToolKit的toolbar中的Preview Entity Class按鈕,出現該表的實體映射類預覽視窗。

圖4 預覽實體映射類

5.

檢查目前預覽的實體類,點選生成檔案按鈕,該實體類将被生成到解決方案資料總管目前選中的路徑下。

6.

重複4,5步驟就可以生成其他表的映射實體類。

代碼1.實體映射類

<b>2.2</b><b>對象持久化</b>

Grove提供ObjectOperator實作對映射實體對象的資料庫持久工作,并通過IObjectQuery接口實作對複雜資料庫關系映射實體的查詢,主要接口如下:

方法

說明

Insert

新增一個對象

Update

根據條件更新一個對象

Remove

根據條件删除一個對象

RemoveChilds

删除所有關系對象

Retrieve

傳回一個對象

RetrieveChilds

傳回所有關系對象

GetDataReader

傳回IDataReader

GetObjectSet

傳回對象集合

GetObjectSource

根據對象定義傳回DataSet

GetCount

從資料源傳回記錄條數

BeginTranscation

在資料庫支援事務的基礎上,開始事務處理

Commit

完成目前事務

Rollback

回退目前事務

<b>2.3</b><b>資料查詢</b>

如一般的關系型資料庫所具有的查詢功能一樣,Grove也有着非常豐富的查詢功能,如對象查詢、函數查詢、子查詢、排序查詢等。這裡對對象查詢做簡單介紹,其它查詢讀者可以自行參考Grove的開發文檔。Grove提供ObjectQuery 幫助ObjectOperator從資料源查詢資料, ObjectOperator 需要通過ObjectQuery解析實體對象中的屬性(System.Arrtibute)定義,并構造查詢語句。ObjectQuery在運作時往往需要定義篩選語句(請參考篩選語句的文法定義)。例如,檢索Customer對象,當State 屬性等于WA的情況:

當檢索需要傳回所有對象時,則不需要定義篩選語句

<b>2.4</b><b>篩選語句的文法定義</b>

在ObjectQuery中使用的篩選允許你在定義的時候,根據使用面向對象文法規則進行定義篩選語句。

操作

描述

!, not

用于比較布爾型,例如:

!Order.CustomerID.Contains(Customer.CustomerID)

&lt;, &gt;, &lt;= , &gt;=

用于值比較,例如:

Order.Quantity &gt;= 12

=, !=, &lt;&gt;, = =

用于值判斷,例如:

Customer.Country = 'USA' and Customer.Region != 'WA'

and, &amp;&amp;

用于邏輯判斷,例如:

Customer.Country = 'USA' and Customer.Region = 'WA'

or, ||

Customer.LastName = 'Smith' or Customer.LastName = 'Jones'

以上就是ORM的簡單實作,複雜的關系對象映射及關系映射實體的查詢也是ORM中尤為重要的一塊處理,為了屏蔽各資料庫之間的SQL差異,很多好的ORM架構都提供一種符合面向對象語言本身文法規則的Query Language支援,例如實作對資料庫函數的支援時,會通過定義一些公開的,與程式設計語言接近的語言來實作,比如說定義Object.Size(),Object.Sum()等類方法式操作文法,在邏輯判斷的時候提供一些語言本身的邏輯運算符支援,比如c#中的&amp;&amp;表示and,||表示or等等這些一系列的面向對象程式設計風格的支援,都很好地為基于關系型資料庫支援的系統開發向“面向對象”提供了有力的支援。Grove目前對關系對象查詢有很好的支援,感興趣可以到Grove的網站了解詳細資訊。

本文轉自BearRui(AK-47)部落格園部落格,原文連結:  http://www.cnblogs.com/BearsTaR/archive/2006/05/24/Grove.html  ,如需轉載請自行聯系原作者