- 浏览: 73123 次
- 来自: ...
最近访客 更多访客>>
文章分类
最新评论
-
LeoChowComtop:
楼主的脚步似乎有错误正确的应该是String.prototyp ...
javascript 检查中文字符串的长度 -
cpsing:
路在哪?我在找…..
...
如何编写高质量的代码 -
cpsing:
用 Eclipse 插件提高代码质量
如何编写高质量的代码
The .NET ORM Architecture(.Net ORM 架构)
The .NET ORM Architecture(.Net ORM 架构)
一、Grove描述
Grove是为.Net项目开发而设计的一个组件。Grove ORM Development Toolkit包含包含Grove和Toolkit两部分内容,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 type与Microsoft 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 |
SQL_DECIMAL | Decimal |
SQL_DOUBLE | Double |
SQL_GUID | Guid |
SQL_INTEGER | Int32 |
SQL_LONG_VARCHAR | String |
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 为每一个对象提供了基本的持久性方法,比如insert、insert, 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对象下的BeginTransaction、Commit和Rollback方法。如果你的数据源支持事务,你可以使用这些方法。或者你也可以有选择支持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 join、left 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 Toolkit中Relation 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方法来定义使用数据库函数,如COUNT、SUM、MAX、MIN等,下面例子显示了它们基本用法。
[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
Filter是ObjectOperator被用来查询对象一个查询语言,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"
相关推荐
"ASP.NET 3.5 Application Architecture and Design"的主题着重于如何在实际项目中运用ASP.NET 3.5进行应用程序的架构和设计。 1. **ASP.NET 3.5的基础结构**:ASP.NET 3.5基于.NET Framework 3.5,引入了LINQ...
首先,三层架构(也称为N-Tier Architecture)是为了实现应用程序组件之间的松耦合,它将应用逻辑分为三个主要部分:表现层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access ...
随着ORM(Object-Relational Mapping)技术的发展,Entity Framework成为.NET平台上的主流ORM框架,它简化了数据库操作,将数据库表映射为对象模型,实现了数据库操作的代码抽象。 在.NET平台上,我们还需要关注...
NLAY标签可能代表“Network Layer”或“N-Tier Architecture”,指的是网络通信层或分层架构。在多层架构中,网络层负责处理客户端和服务器之间的通信,通常包括HTTP请求、WCF服务、RESTful API等。理解并正确实现这...
另外,ADO.NET Entity Framework作为ORM(对象关系映射)工具,允许开发者以面向对象的方式操作数据库,减少了对SQL语句的依赖,提高了开发效率。 本书《ASP.NET 3.5开发大全》可能会涵盖以上所有内容,同时可能还...
本篇文章将深入探讨一个基于泛形和面向服务架构(Service-Oriented Architecture, SOA)设计思想的.NET框架Demo代码,帮助读者理解并掌握其核心概念和技术。 首先,我们来谈谈“泛形”。泛形是.NET框架中的一个重要...
- **企业级应用架构(NHibernate+Spring.Net+MVC3+WCF)**:这个架构强调了ORM、依赖注入、Web服务和MVC的结合,旨在创建高度灵活、可扩展和易于维护的大型企业系统。通过NHibernate处理数据持久化,Spring.Net提供...
Entity Framework是一个支持.NET的对象关系映射(ORM)框架,它允许开发者以对象的形式操作数据库,而不需要编写大量的SQL代码。使用Entity Framework可以大大减少代码量,并提高数据访问的效率。 本文档还提到了N...
### 开源应用程序架构二(The Architecture of Open Source Applications 2) #### 概述 《开源应用程序架构二》是一本深入探讨多种开源项目设计细节和技术实践的专业书籍。本书沿用了第一卷的成功模式,通过专家...
13. **Microservices Architecture**:在.NET环境中,可以使用微服务架构来设计可扩展、松耦合的系统,每个服务独立部署和升级。 14. **Git and GitHub**:作为版本控制工具,Git和GitHub在.NET开发中扮演着重要...
例如Martin Fowler在《Patterns of Enterprise Application Architecture》一书中,将整个架构分为三个主要的层:表示层、领域层和数据源层。作为领域驱动设计的先驱Eric Evans,对业务逻辑层作了更细致地划分,细分...
在ASP.NET开发中,一个重要的设计理念是采用“三层架构”(Three-Tier Architecture),这种架构模式有助于提高代码的可维护性、可重用性和可扩展性。以下是关于ASP.NET开发原理及其三层架构的详细解释。 **ASP.NET...
5. **实体框架(Entity Framework)**:.NET的ORM(对象关系映射)工具,简化了数据库操作,将数据库操作与业务逻辑解耦。 6. **仓储模式(Repository Pattern)**:为业务对象提供一个统一的访问接口,隐藏数据...
.NET架构(.NET Architecture): 介绍了.NET平台的基础架构,如何支持跨语言编程和构建不同种类的应用程序。 核心C#(Core C#): 涵盖了C#的基础知识,包括语法、类型系统、控制结构和程序流程。 对象和类型...
本压缩包文件聚焦于ASP.NET的三层架构(也称为N-Tier Architecture)和LINQ(Language Integrated Query,语言集成查询)的学习,同时包含了相关的实验和试验报告,旨在帮助学习者深入理解这两个核心概念。...
三层架构(Three-Tier Architecture)是一种软件设计模式,它将应用程序分为三个逻辑部分:表示层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)。这种架构的主要...