.Grove—— .Net下的ORM框架

 

.Grove—— .Net下的ORM框架

 

 

參見原文:http://grove.91link.com(英)

Grove下載

The .NET ORM Architecture.Net ORM 架構)

一、Grove描述

Grove是爲.Net項目開發而設計的一個組件。Grove ORM Development Toolkit包含包含GroveToolkit兩部分內容,Grove基於.Net框架,支持多數據,提供標準的拖曳、三層及多層的開發模式。

二、Grove工具包

Grove工具是一個基於.Net開發環境的附件,它能夠從數據源直接查看到實體類與XML描述。例如單一對象或者關係對象(互相聯繫的對象),這裏的幾個抓圖屏幕顯示了它的一些描述。

三、The ObjectOperator

The ObjectOperator 與數據進行通信,它使用 AppSettingManager 來設置數據源,如設置數據庫服務器的連接字符串。The ObjectOperator 使用Attributes決定在數據源中的字段與表與一個對象成員的映射關係,即字段與表做爲一個持久性對象來使用與從數據源中返回一個對象成員屬性。

The ObjectOperator 可能使用一個存在連接字符串來構造,或者你必須確保在當前項目的Web.Config文件中的ConfigurationSettings存在AppSettings節點,並設置Key屬性值爲"DBConnString",Value值爲一個正確的連接字符串。

下面的例子顯示了ObjectOperator的創建:

 

 

[System.Configuration.ConfigurationSettings.AppSettings["DBConnString"];]

ObjectOperator oo=new ObjectOperator();

 

 

[Custom Connection String]

ObjectOperator oo=new ObjectOperator("Server=localhost;Uid=sa;Pwd=sa;Database=sample");

 

 

ObjectOperator提供了下列方法,主要功能是從一個數據源中返回對象,或者返回給數據源對象。

Method

Description

Insert

Insert an object into the data source

Update

Update an object

Remove

Delete an object from the data source

RemoveChilds

Delete child objects

Retrieve

Returns an object from the data source

RetrieveChilds

Returns child objects from the data source

GetDataReader

Returns an IDataReader from the data source

GetObjectSet

Returns a collection of object values

GetObjectSource

Returns a DataSet which contain the data source of the object

GetCount

Returns a records count of the data source

BeginTranscation

Begins a transaction at the data source, if transactions are supported by the data source. 

Commit

Commits the current transaction.

Rollback

Rolls back the current transaction.

 

 

四、The ObjectQuery

ObjectQuery被用來幫助ObjectOperator從數據源中獲得對象,例如,ObjectOperator需要它來得到一個“QueryString”而加以執行,ObjectQuery使用Attributes關鍵字決定當前對象引用單表或多表。

一個ObjectQuery對象的構造,通過傳遞一個對象類型或一個過濾字符串給ObjectQuery的構造函數,詳細過濾定義,參考Filter syntax (過濾語法)。例如,下面的ObjectQuery搜索所有State值等於“WA”的Customer對象。

ObjectQuery query=new ObjectQuery(typeof(Customer),"this.State='WA'");

爲返回對象的所有數據類型,指定一個空的字符中作爲你的過濾條件,如下例子:

ObjectQuery query=new ObjectQuery(typeof(Customer),"");

Filter 允許你在關係對象中使用“Contains”關鍵字定義字查詢,你可以查詢出存在定單數據超過50

所有Customer對象。

ObjectQuery query = new ObjectQuery(typeof(Customer),”Order.CustomerID.Contains(this.CustomerID)”);

query.DeclareSubset(typeof(Order),”Order.Quantity>50”);

五、The FilterExpression(過濾表達式)

FilterExpression 是一個可擴展的過濾,即FilterExpression允許你偏離ObjectQuery來爲一些操作構造許多複雜的條件,例如通過自定義條件來更新一個對象。

一個FilterExpression的創建,通過傳遞一個對象類型或傳遞一個過濾字符串給ObjectQuery的構造函數。

例如下面的FilterExpression定義了一個State等於“WA”的所有“Customer類型”的對象的過濾表達式。

FilterExpression filterex = new FilterExpression(typeof(Customer),”this.State=’WA’”);

Filter 允許你在關係對象中使用“Contains”關鍵字定義字查詢,你可以查詢出存在定單數據超過50的所有Customer對象。

 

 

FilterExpression filterex=new FilterExpression(typeof(Customer),"Order.CustomerID.Contains(this.CustomerID)");
filterex.DeclareSubset(typeof(Order),"Order.Quantity>50");

有時,我們需要更新一個對象的屬性,而不更新其它屬性。例如,僅僅需要更新Customer對象中State屬性值,通過自定條件,如下所示:

ObjectOperator oo=new ObjectOperator();
oo.Update(typeof(Customer),filerex,"this.Status=1");

這個例子意思是將定單數量(Order)大於50的所有客戶(Customer)的“State”的值設爲1

Persisting Objects (持久性對象) 

一、Mapping Object Properties(映射對象屬性)

         Grove ORM architecture 要求每一個持久性對象包含一個屬性,這個屬性值表示一個來自數據源的表的名字,此表名標示符在Object Mapping (對象映射)中用DataTable屬性關鍵字來表示。

當從一個數據源中映射過來時,這PK(主鍵字段)需要一個屬性,來表示此字段爲主鍵字段,例如,

[KeyField("CustomerID")]
public int CustomerID{get; set;}

如果這PK Field(主鍵字段)不唯一,你必須確保這“KeyType”是“UniquelType.OtherDefinition”,下面的例子表示了字段類型是一個數據不唯一的String(字符串)類型。

[KeyField("Field Name",KeyType=UniqueIDType.OtherDefinition)]
public string PropertyName{get; set;}

並且,這PK field也可以使用ForeignKeyField屬性來表示來自數據源的一個字段名(外鍵)。、

[DataTable("Orders")]
public class Order
{
    [ForeignKeyField("CustomerID")]
    public int CustomerID{get; set;}
}

另外,其它字段也需要一個名爲DataField的屬性來表示來自數據源的表的字段。

[DataField("Field Name")]
public type PropertyName{get; set;}

當將數據源(表)映射成爲對象時,你需要量將the .NET framework data provider data types 映射成爲NET framework data types

下面的表顯示了.NET Framework typeMicrosoft SQL Server, OLE DB, and ODBC.的比較。詳細信息請參考.NET Framework Developer's Guide

注意:在.NET Framework data provider data types下的Null值被取代爲DBNull.Value

.NET Framework Data Provider for SQL Server

SQL Server type

.NET Framework type

bigint

Int64

binary

Byte[]

bit

Boolean

char

String Char[]

datetime

DateTime

decimal

Decimal

float

Double

image

Byte[]

int

Int32

money

Decimal

nchar

String Char[]

ntext

String Char[]

numeric

Decimal

nvarchar

String Char[]

real

Single

smalldatetime

DateTime

smallint

Int16

smallmoney

Decimal

sql_variant

Object *

text

String Char[]

timestamp

Byte[]

tinyint

Byte

uniqueidentifier

Guid

varbinary

Byte[]

varchar

String Char[]

.NET Framework Data Provider for OLE DB

OLE DB type

.NET Framework type

DBTYPE_I8

Int64

DBTYPE_BYTES

Byte[]

DBTYPE_BOOL

Boolean

DBTYPE_BSTR

String

DBTYPE_HCHAPTER

Supported through the DataReader

DBTYPE_STR

String

DBTYPE_CY

Decimal

DBTYPE_DATE

DateTime

DBTYPE_DBDATE

DateTime

DBTYPE_DBTIME

DateTime

DBTYPE_DBTIMESTAMP

DateTime

DBTYPE_DECIMAL

Decimal

DBTYPE_R8

Double

DBTYPE_ERROR

ExternalException

DBTYPE_FILETIME

DateTime

DBTYPE_GUID

Guid

DBTYPE_IDISPATCH *

Object

DBTYPE_I4

Int32

DBTYPE_IUNKNOWN *

Object

DBTYPE_NUMERIC

Decimal

DBTYPE_PROPVARIANT

Object

DBTYPE_R4

Single

DBTYPE_I2

Int16

DBTYPE_I1

Byte

DBTYPE_UI8

UInt64

DBTYPE_UI4

UInt32

DBTYPE_UI2

UInt16

DBTYPE_UI1

Byte

DBTYPE_VARIANT

Object

DBTYPE_WSTR

String

DBTYPE_UDT

not supported

DBTYPE_VARNUMERIC

not supported

.NET Framework Data Provider for ODBC

ODBC type

.NET Framework type

SQL_BIGINT

Int64

SQL_BINARY

Byte[]

SQL_BIT

Boolean

SQL_CHAR

String
Char[]

SQL_DECIMAL

Decimal

SQL_DOUBLE

Double

SQL_GUID

Guid

SQL_INTEGER

Int32

SQL_LONG_VARCHAR

String
Char[]

SQL_LONGVARBINARY

Byte[]

SQL_NUMERIC

Decimal

SQL_REAL

Single

SQL_SMALLINT

Int16

SQL_TINYINT

Byte

SQL_TYPE_TIMES

DateTime

SQL_TYPE_TIMESTAMP

DateTime

SQL_VARBINARY

Byte[]

SQL_WCHAR

String Char[]

SQL_WLONGVARCHAR

String Char[]

SQL_WVARCHAR

String Char[]

下面的代碼,表示一個簡單的一個映射關係:

[DataTable("Customers")]
public class Customer
{
    int customerID;
    string customerName;
    int parentID;
    ....
    [KeyField("CustomerID")]
    public int CustomerID
    {
        get{return this.customerID;}
    }
    [DataField("CustomerName")]
    public string CustomerName
    {
        get{return this.customerName;}
        set{this.customerName=value;}
    }
    [ForeignKeyField("ParentID")] 
    public int ParentID
    {
        get{return this.parentID;}
        set{this.parentID=value;}
    }
}

二、Persisting Object Data(持久性對象數據)

ObjectOperator 爲每一個對象提供了基本的持久性方法,比如insertinsert, update, delete以及從一個數據源返回一個對象,或者通過RetriveChilds,GetObjectSet等方法來獲得一個相關的對象。

因此,程序員可以擴展這些方法爲更多條件的選擇,下面的代碼顯示了它的用法。

[DataTable("Customers")]
public class Customer
{
    int customerID;
    ...
    ArrayList orders=null;
    [KeyField("CustomerID")]
    public int CustomerID
    {
        get{return this.customerID;}
    }
    public ArrayList Orders
    {
        get{
            if(orders==null && customerID>0)
                orders=(new ObjectOperator()).RetrieveChilds(typeof(Order),customerID)
            return orders;
        }
    }
}

下面的例子給出了一些基本的用法:

[persist a new object ]
Customer c=new Customer();
c.CustomerName="rainbow co.";
oo.Insert(c);


[update an object]
c.CustomerID=1000;
c.CustomerName="rainbow-co.";
oo.Update(c);


[update an retrieved object]
Customer c=(Customer)oo.Retrieve(typeof(Customer),1000);
c.CustomerName="rainbow.co"
oo.Update(c);

[update an object with new regulation]
Product p=(Product)oo.Retrieve(tyoeof(Product),guidString);
p.ProductID=newGuidString;
oo.Update(p,"this.ProductID=guidString");

Note the existing KeyField type is UniqueIDType.OtherDefinition,and need to update that.

[update objects perproty without other properties ]
oo.Update(typeof(Customer),"this.CustomerID<1000","this.Status=2");

Note update status to 2 for customer objects with id small than 1000.

[delete an object]
oo.Remove(c);

[delete related child objects]
int customerID=1000;
oo.RemoveChilds(typeof(Order),customerID);

Note the Order object must be contain a ForeignKeyField attribute for the FK field(CustomerID

三、Retrieve Object Data(返回一個對象數據)

ObjectOperator提供了極其豐富的方式,通過ObjectQuery來返回一個對象或結果集合,詳細信息請查看Query for objects

下面的例子顯示了它的基本用法:

[return an existing object]
Customer c=(Customer)oo.Retrieve(typeof(Customer),1000);

[return a related child collection]
ArrayList orders=oo.RetrieveChilds(typeof(Order),c.CustomerID);

[return a related child collection through ObjectQuery]
ArrayList orders=oo.GetObjectSet(new ObjectQuery(typeof(Order),"this.CustomerID="+c.CustomerID));

[return DataSet]
EntityData orders= oo.GetObjectSource(new ObjectQuery(typeof(Order),"this.CustomerID="+c.CustomerID));

Note EntityData is an object extends the DataSet from the System.Data namespace

四、Grove Transaction(事務)

Grove 架構支持基本的事務處理方法,通過ObjectOperator對象下的BeginTransactionCommitRollback方法。如果你的數據源支持事務,你可以使用這些方法。或者你也可以有選擇支持isolation level(隔離級別), 通過從System.Data命令空間裏使用IsolationLevel 枚舉值。如果你不使用Isolation level,缺省使用ReadCommitted事務級別。

注意:引用System.Data命名空間。

oo.BeginTranscation();
try{
      oo.Insert(c);
      oo.Commit();
}
catch{
      oo.Rollback();
}

Querying for objects

一、Mapping Relation Object Properties

Grove 架構支持映射多表到一個對象——關係對象被用來做更復雜的查詢,關係對象映射制授權你在兩表之間指定連接類型,即你可以有選擇地使用inner joinleft outer join right outer join或者full join爲一個屬性,被用在表間的映射關係。

在映射時,關係必須包含一個成員,顯示結果名(執行返回一個數據集)並指定FROM子句,在此成員的屬性BeginWithTable中沒有FROM關鍵字。下面的代碼表明瞭怎樣將多表映射成爲一個關係對象,從數據源中選擇需要返回的字段爲這個對象。

[RelationTable("PersonRelationQuery",BeginWithTable="Person")]
public class PersonInfo
{
      [RelationReflect("Person","Address",JoinType=TableJOINType.LEFTOUTERJOIN)]
      [RelationField("Id","PersonID")]
      public string Relationship_1
      {
            get{return "[Person].[Id]=[Address].[PersonID]";} 
      } 
      int _Id;
      [DataField("Id",TableName="Person")]
      public int PersonId
      {
            get{return this._Id;}
            set{this._Id=value;}
      }
      string _Name;
      [DataField("Name",TableName="Person")]
      public string PersonName
      {
            get{return this._Name;}
            set{this._Name=value;}
      }
      string _Street;
      [DataField("Street",TableName="Address")]
      public string StreetInfo
      {
            get{return this._Street;}
            set{this._Street=value;} 
      }
}

Grove ToolkitRelation Query Builder能夠幫助你,隨意映射。

二、Creating Object Queries

Object queries通過創建一個ObjectQuery 對象實例指定。關於ObjectQuery的更多細節,請查看The Object Query Overview.

[no filter query]
ObjectQuery query=new ObjectQuery(typeof(Customer),"");

[filter query]
ObjectQuery query=new ObjectQuery(typeof(Customer),"this.State='WA'");

[object oriented syntax filter]
ObjectQuery query=new ObjectQuery(typeof(Customer),"this.State='WA' && this.Country=='USA'");

[sub-set with filter query]
ObjectQuery query=new ObjectQuery(typeof(Customer),"Order.CustomerID.Contains(this.CustomerID)"); query.DeclareSubset(typeof(Order),"Order.Quantity>50");

[sub-set without filter query]
ObjectQuery query=new ObjectQuery(typeof(Customer),"PersonInfo.PersonId.Contains(this.CustomerID)");
query.DeclareSubset(typeof(PersonInfo));

ObjectQuery允許用戶使用AddCandidate方法來定義使用數據庫函數,如COUNTSUMMAXMIN等,下面例子顯示了它們基本用法。

[count query]
ObjectQuery query=new ObjectQuery(typeof(Customer),"this.CustomerName<>''");
query.AddCandidate("this.CustomerID.size()");

NOTE the same as use query.AddCandidate("*.size()");

[sum query]
ObjectQuery query=new ObjectQuery(typeof(Person));
query.AddCandidate("this.Age.sum()");

[maximum query]
ObjectQuery query=new ObjectQuery(typeof(Person));
query.AddCandidate("this.Age.max()");

[minimum query]
ObjectQuery query=new ObjectQuery(typeof(Person));
query.AddCandidate("this.Age.min()");

[average query]
ObjectQuery query=new ObjectQuery(typeof(Person));
query.AddCandidate("this.Age.avg()");

四、Returning Objects

IDataReader reader=oo.GetDataReader(new ObjectQuery(typeof(Customer),""));

ArrayList customers=oo.GetObjectSet(new ObjectQuery(typeof(Customer),""));

EntityData result=oo.GetObjectSource(new ObjectQuery(typeof(Customer),""));

五、Using Filter

IDataReader reader=oo.GetDataReader(new ObjectQuery(typeof(Customer),"this.State='WA'"));

關於更多信息,請查看The ObjectQuery and The FilterExpression

 

 

六、Using Sub-set for queries

 

 

ObjectQuery允許你定義子集查詢,即可以使用“IN”或“NOT IN”來查詢,需要使用Contains關鍵來。

[syntax]
Object.Property.Contains(this.Property)

Note NOT IN query need contain "!" before the head.

ObjectQuery query=new ObjectQuery(typeof(Customer));
query.Filter="Order.CustomerID.Contrains(this.CustomerID)";
query.DeclareSubset(typeof(Order),"Order.Quantity>50");
ArrayList customers=oo.GetObjectSet(query);

七、Filter Syntax

FilterObjectOperator被用來查詢對象一個查詢語言,Filter允許你使用標準面嚮對象語言的關係操作符來查詢對象。在一個查詢中你可以遍歷對象的關係,也可以使用標準的面向對象關係操作符進行復雜的值比較。

Operator

Description

!, not

Used to perform a Boolean operation on a single value. For example:

!Order.CustomerID.Contains(Customer.CustomerID)

<, >, <= , >=

Used to compare one value to another. For example:

Order.Quantity >= 12

=, !=, <>, = =

Used to compare exact values. For example:

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

and, &&

Used to perform a logical junction. For example:

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

or, ||

Used to perform a logical disjunction. For example:

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

 

 

八、Order String(排序字符)

Order String 允許你在返回對象時控制排序。

[desc]
ObjectQuery query=new ObjectQuery(typeof(Customer),""); 
query.OrderString="this.CustomerID desc";

[multi order condition]
query.OrderString="this.CustomerName,this.GetDate desc"

 

 

 

 


發佈了1 篇原創文章 · 獲贊 1 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章