日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

开源XDesigner ORM 框架设计

發(fā)布時間:2025/3/15 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 开源XDesigner ORM 框架设计 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

XDesigner ORM 框架設(shè)計

袁永福 2011-01-20

?

?最新版本源代碼下載地址 http://files.cnblogs.com/xdesigner/XDesignerORM.zip?.

前言

目前業(yè)界已經(jīng)流行著很多ORM框架,但筆者還是要開發(fā)自己的ORM框架,在此不展開關(guān)于是否需要重復(fù)發(fā)明輪子的討論,反正是要開發(fā)這個ORM框架,名為XDesignerORM,簡稱XORM。筆者的數(shù)據(jù)庫開發(fā)經(jīng)驗不大多,但有著很多的圖形軟件開發(fā)經(jīng)驗,相信筆者的一些開發(fā)理念能融入到這個ORM框架中,形成一個獨具特色的具有實際應(yīng)用價值的框架程序。鑒于工作量大,而且避免閉門造車,筆者選擇了開源模式。

設(shè)計理念

首先講講筆者的設(shè)計理念,ORM框架就是為了實現(xiàn)應(yīng)用程序中的一個個實體對象和數(shù)據(jù)庫記錄之間的來回映射關(guān)系。其實實體對象和數(shù)據(jù)庫記錄是業(yè)務(wù)實體模型的兩種表現(xiàn)形式,兩者應(yīng)該是平等的,但筆者先嘗試下從應(yīng)用程序的實體對象為中心的設(shè)計策略。這樣筆者可以借鑒對象序列化的思想,可以將數(shù)據(jù)保存到數(shù)據(jù)庫中視為對象的針對數(shù)據(jù)庫的序列化過程。

.NET框架已經(jīng)提供了三種序列化過程:1.二進(jìn)制序列化;2.XML序列化;3.CodeDom序列化。最常用的就是XML序列化,而且WebService就是以XML序列化為底層基礎(chǔ)的。

XML序列化中,對象中的屬性是和XML文檔中的節(jié)點一一對應(yīng),.NET框架并提供一種通用的XML序列化操作類型System.Xml.XmlSerializer來完整的完成XML序列化和反序列化過程。絕大多數(shù)情況下,開發(fā)者無需考慮也無需編寫代碼來實現(xiàn)對象和XML文檔之間的映射過程,而在一些必要的情況下為對象類型及其成員添加System.Xml.XmlElementAttribute等說明性質(zhì)的特性。

既然XDesignerORM本質(zhì)上是基于數(shù)據(jù)庫的對象序列化過程。于是可以參考Xml序列化的原理,應(yīng)當(dāng)包含以下幾個部分。

1?數(shù)據(jù)庫處理層。能盡量屏蔽各種特定的數(shù)據(jù)庫的特性。比如MS SQL Server, Oracle , DB2使用的SQL語法的些許不同。初期為了簡單,只支持MS SQL Server,不支持事務(wù)。

2?ORM引擎。框架的核心,能讀取數(shù)據(jù)庫記錄并創(chuàng)建對象實例,也能根據(jù)對象實例來更新數(shù)據(jù)庫。

3?ORM特性標(biāo)記類型。類似XmlTypeAttribute等特性,用于知名對象類型和數(shù)據(jù)庫之間的映射關(guān)系。在默認(rèn)情況下,對象類型名稱就是數(shù)據(jù)庫表的名稱,對象屬性的名稱就是數(shù)據(jù)庫字段的名稱。

?

比如在一個客戶數(shù)據(jù)管理系統(tǒng)中,存在以下幾種類型

CustomerClass,表示客戶的基本信息。

OrderClass,表示訂單的基本信息。

ProductClass,表示貨物的基本信息。

在該系統(tǒng)中,存在多個客戶,而一個客戶有多個訂單,一個訂單包含多個貨物。于是構(gòu)成了客戶、訂單、貨物的三層的樹狀結(jié)構(gòu)。

而在本程序的演示數(shù)據(jù)庫SkyDemo.mdb中有個數(shù)據(jù)表Customers就保存著很多客戶的基本信息。于是一個CustomerClass類型的對象實例序列化就成為Customers數(shù)據(jù)表中的一條記錄。

類似的可以建立其以下的映射關(guān)系

對象類型

數(shù)據(jù)表

CustomerClass

Customers

OrderClass

Orders

ProductClass

Products

?

.NET中,實現(xiàn)對象屬性和數(shù)據(jù)庫字段的映射關(guān)系不算很復(fù)雜。但需要實現(xiàn)對象之間的關(guān)聯(lián)結(jié)構(gòu)與數(shù)據(jù)庫記錄之間的映射關(guān)系。也就是說需要在數(shù)據(jù)庫中保存對象之間的一對多的關(guān)系,其實多對多的關(guān)系實際上可以看做雙向的一對多的關(guān)系。

XORM應(yīng)該可以處理對象之間的多對多的關(guān)系。比如,一個CustomerClass客戶對象有多個訂單記錄。于是可以為CustomerClass類型添加一個名為Orders的屬性,該屬性返回客戶名下的所有的OrderClass對象實例。XORM框架讀取數(shù)據(jù)庫創(chuàng)建一個CustomerClass對象實例時也應(yīng)該讀取數(shù)據(jù)庫創(chuàng)建該客戶名下的訂單信息并設(shè)置CustomerClass對象的Orders屬性。

這樣做有一個性能問題,當(dāng)應(yīng)用程序僅僅讀取客戶的基本信息,而無需處理客戶名下的訂單信息,此時XORM框架還完整的讀取該客戶名下的訂單信息,這浪費時間浪費內(nèi)存。于是XORM框架應(yīng)當(dāng)支持延遲加載,只有當(dāng)應(yīng)用程序訪問CustomerClass對象的Orders屬性時才會再次讀取數(shù)據(jù)并填充訂單列表。

在此可以參考代碼注入的技術(shù)來截獲應(yīng)用系統(tǒng)訪問實體數(shù)據(jù)類型的需要延遲加載的屬性。

比如當(dāng)使用以下代碼定義CustomerClass類型的Orders屬性

Private OrderClass[] myOrders = null;

Public virtual OrderClass[ ] Orders

{

?????? Get

?????? {

????????????? Return myOrders;

?????? }

?????? Set

?????? {

????????????? myOrders = value;

?????? }

}

則采用動態(tài)編譯技術(shù)從CustomerClass類型動態(tài)的創(chuàng)建一個類型,該類型重載了Orders屬性,其代碼如下

Public override OrderClass[] Orders

{

?????? Get

?????? {

????????????? If( base.Orders == null )

????????????? {

???????????????????? // 讀取Orders數(shù)據(jù)表并生成 OrderClass 對象實例數(shù)組。

???????????????????? Base.Orders = XORM.ReadObjects(“Orders” , typeof( OrderClass ) );

????????????? }

????????????? Return base.Orders;

?????? }

?????? Set

?????? {

????????????? Base.Orders = value;

?????? }

}

這樣當(dāng)應(yīng)用程序調(diào)用XORM框架生成CustomerClass實例時,實際上獲得的不是CustomerClass類型的實例,而是從CustomerClass上面派生的類型的實例,但使用上沒有什么區(qū)別,應(yīng)用程序仍然能將其當(dāng)做CustomerClass類型來使用。

因此編寫實體類型時,對于所有需要延遲加載的屬性都需要設(shè)置為可以重載的模式,對于C#也就是添加virtual關(guān)鍵字,而且該類型是可以派生的,不能是密封類型,對于C#也就是不能在類型前面加上sealed 關(guān)鍵字。

延遲加載不但能用于處理子對象列表,也能用于處理包含大量的數(shù)據(jù)的字段,比如保存圖片的二進(jìn)制字段。

?

XORM框架還需要處理對象緩存的功能,尤其是在處理業(yè)務(wù)對象存在多對多的關(guān)系的時候,可能會出現(xiàn)對象重復(fù)加載的現(xiàn)象,此時需要重復(fù)使用已經(jīng)加載的實體對象,目前暫不考慮。

使用XORM框架,實體對象與數(shù)據(jù)庫的映射關(guān)系將使用特性附加在程序代碼中,當(dāng)數(shù)據(jù)庫表或者字段發(fā)生變更,此時需要修改程序源代碼,重新編譯重新部署,這樣降低了程序的靈活度。為此XORM框架將同時支持程序代碼中的特性和XML配置文件的方式。XOMR框架首先分析程序集中的元數(shù)據(jù),然后再分析XML配置文件,最后確定出實體對象和數(shù)據(jù)庫的映射關(guān)系。

?

XORM框架能否快速方便的應(yīng)用,需要配套使用方便的系統(tǒng)開發(fā)和實施輔助工具程序。這些工具程序包括:

1?代碼生成器。能根據(jù)數(shù)據(jù)庫的表和字段結(jié)構(gòu)自動生成能用于XORM框架的實體類型的源代碼。也就是生成類似上面提到的CustomerClassOrderClass等類型的源代碼。代碼生成器能根據(jù)數(shù)據(jù)庫中定義的外鍵信息生成子對象列表屬性。比如自動生成CustomerClass類型的Orders屬性,并自動設(shè)置為延遲加載。

2?實體類型和數(shù)據(jù)庫的對比工具。能檢查已經(jīng)開發(fā)好的實體類型與指定數(shù)據(jù)庫的映射關(guān)系,幫助開發(fā)者調(diào)試和部署XORM框架。

3?映射配置文件編輯器。能幫助開發(fā)者準(zhǔn)確的寫出指定的數(shù)據(jù)庫和實體類型之間的映射關(guān)系配置文件。

?

模塊劃分

XORM框架大體分為以下幾個程序模塊

ORM DOM

ORM DOM 就是一種描述O/R映射關(guān)系的文檔對象模型。一個實用的O/R映射關(guān)系內(nèi)部比較復(fù)雜,是難于用平面的數(shù)據(jù)結(jié)構(gòu)來描述的,而文檔對象模型擅長于描述復(fù)雜的數(shù)據(jù)結(jié)構(gòu),因此在此自定義了一種ORM DOM來描述O/R映射關(guān)系。

ORM DOM主要包含了以下幾種類型

1.???????? ORMProjectInfo類型,是DOM結(jié)構(gòu)的頂級對象,是其他模塊訪問ORM DOM的唯一入口點。

2.???????? ORMTypeInfo類型,用于描述一種實體類型和數(shù)據(jù)庫表的映射關(guān)系。

3.???????? ORMPropertyInfo類型,用于描述實體類型的某個屬性和數(shù)據(jù)庫中的某個字段的映射關(guān)系,還指明該字段是否延遲加載、是否是只讀的、存儲格式等等信息。

4.???????? ORMRelationInfo類型,用于描述實體之間的關(guān)系,包括一對多的關(guān)系和多對多的關(guān)系。

?

ORM DOM 是可以參與XML序列化和反序列化的,因此這為未來同時支持O/R配置文件做好基礎(chǔ)。

?

此外ORM DOM還定義了ORMTypeMappingHelper類型。該類型定義了執(zhí)行數(shù)據(jù)庫映射關(guān)系的接口,包括初始化查詢、新增、修改和刪除數(shù)據(jù)庫記錄的SQL語句。而其他模塊將從整個類型派生出實際使用的幫助類型,而框架引擎在該類型的派生類型的幫助下實現(xiàn)O/R映射。

ORM DOM中已經(jīng)實現(xiàn)了ReflectionORMTypeMappingHelper,該類型是基于反射技術(shù)的,運行速度比較慢。而框架將使用動態(tài)編譯技術(shù)生成快速的映射幫助類型。

DataBase

這是本框架的數(shù)據(jù)庫操作模塊,包含了ORMDataBaseORMDBCommand類型。

ORMDBCommand類型用于存儲SQL命令文本以及配套參數(shù)值。

ORMDataBase類型用于管理數(shù)據(jù)庫連接。

Dynamic Compile

這是本框架的動態(tài)編譯功能模塊,包括了CodeGeneratorDynamicCompiler類型。

CodeGenerator類型是代碼生成器,是根據(jù)ORM DOM的信息,生成操作特定實體類型和特定數(shù)據(jù)表之間的映射關(guān)系的C#源代碼文本。這段源代碼會從ORMTypeMappingHelper類型派生出新的類型并實現(xiàn)其中的方法。

在生成的代碼中,會根據(jù)需要從實體類型派生出臨時類型,重載需要延遲加載的屬性,這樣實現(xiàn)了實體屬性數(shù)據(jù)延遲加載的功能。

例如實體類型CustomerClass描述一個客戶的基本信息,其定義如下

[ORMType("Customers")]

public class CustomerClass

{

??? public CustomerClass()

??? {

??? }

?

??? private string _ID = null ;

??? [ORMKeyField()]

??? [ORMField("CustomerID")]

??? [ORMIDGenerate( ORMIDGenerateStyle.GUID )]

??? public virtual string ID

??? {

??????? get { return _ID; }

??????? set { _ID = value; }

??? }

??? private string _WebSite = null;

?

??? public string WebSite

??? {

??????? get { return _WebSite; }

??????? set { _WebSite = value; }

??? }

?

??? private List<OrderClass> _Orders = null;

??? [ORMRelation( ORMRelationStyle.OneToMany , "CustomerID",UniteDelete=true)]

??? [ORMDelay()]

??? public virtual List<OrderClass> Orders

??? {

??????? get { return _Orders; }

??????? set { _Orders = value; }

??? }

}

在這里Orders屬性是該客戶類型下所有的訂單信息列表,為了性能,該屬性是標(biāo)記為延遲加載的。

而代碼生成器在CustomerClass類型派生了新的類型,并重載了Orders屬性,其演示代碼如下。

public class CustomerClass_Temp : CustomerClass

{

??? public CustomerClass_Temp()

??? {

??? }

?

?? ?internal ORMFramework _Work = null;

?

??? public override List< OrderClass> Orders

??? {

??????? get

??????? {

??????????? if (base.Orders == null && this._Work != null)

??????????? {

?

??????????????? OrderClass conditionInstance = new OrderClass();

????? ??????????conditionInstance.Customer = this;

?

??????????????? Array list = this._Work.ReadInstancesByCondition(

??????????????????? conditionInstance,

??????????????????? new string[] { "Customer" });

?

??????????????? List< OrderClass> result = newList< OrderClass>();

?

??????????????? foreach (OrderClass item in list)

??????????????? {

??????????????????? result.Add(item);

??????????????? }

?

??????????????? base.Orders = result;

??????????? }

??????????? return base.Orders;

??????? }

??????? set

??????? {

??????????? base.Orders = value;

??????? }

??? }

}//public class TempClass

在重載的Orders屬性中,若該屬性值為空則調(diào)用ORM框架來查詢數(shù)據(jù)庫,獲得該客戶名下的所有的訂單信息對象,然后填充到訂單列表。如此應(yīng)用程序讀取數(shù)據(jù)庫獲得一個客戶信息對象時并不會導(dǎo)致讀取該客戶名下的訂單信息,只有應(yīng)用程序訪問客戶對象的Orders屬性值時采用啟用延遲加載。這樣做能比較好的提高性能。

由于需要重載延遲調(diào)用的屬性的,因此需要標(biāo)記為延遲調(diào)用的屬性必須是可以重載的,必須標(biāo)記為abstractvirtualoverride,否則代碼生成器會拋出異常。

?

DynamicCompiler接受代碼生成器生成的C#代碼,調(diào)用微軟.NET框架自帶的C#編譯器生成臨時程序集,然后分析程序集獲得O/R幫助器的類型并創(chuàng)建O/R幫助器實例。這種O/R幫助器具有很高的運行性能,動態(tài)編譯技術(shù)比較好的兼顧靈活和執(zhí)行性能。

?

Engine

這是本框架的核心模塊,包含了ORMEngineORMContext類型。

ORMEngine是本框架的頂級對象,它調(diào)用其他程序模塊,提供了O/R操作的API

ORMContext是執(zhí)行O/R操作過程的上下文信息對象。

?

目前就寫得這么多了,以后繼續(xù)。該ORM框架源代碼的SVN訪問地址為 https://xdesignerorm.svn.sourceforge.net/svnroot/xdesignerorm/??

??????

?

總結(jié)

以上是生活随笔為你收集整理的开源XDesigner ORM 框架设计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。