NDO中的ActiveRecord 简介

本文介绍了ActiveRecord模式在NDO框架中的实现方式及其设计理念,对比了不同ORM框架的性能,并展示了NDO中ActiveRecord的具体使用案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

          我开发的这个ActiveRecord 思想来源于现在非常火爆的Rails框架中的ActiveRecord - 活动记录,该模式来源于国际软件大师Martin Flowler所著的<<企业应用架构模式>>。文中Martin Flowler下了定义:一个对象,它包装数据库表或视图中的某一行,封装数据库访问,并在这些数据上增加了领域逻辑意思是说活动记录是一个实体对象,该实体对象代表数据库表或视图中的一行,并在该实体对象中封装了数据访问逻辑和业务逻辑代码,对象既有数据又有行为。该对象到底是数据对象?DAO对象?BIZ 对象呢? 马丁福莱道:领域模型,即BIZ对象(较业务对象)。ActiveRecord应用最广的是Ruby 中的Rails框架,并且把ActiveRecord的感念又大大延伸了.Rails框架中的ActiveRecord完全可以和JAVA中的hibernate 相比美,该框架中的"简单就是美","约定胜于配置"等敏捷思想深深的影响了我,使我产生开发NQL的一个动力.Rails中的活动记录支持一对多,多队一,多对多等对象关系映射模式.我做的ActiveRecord目前支持单表映射,对于一对多,多队一,多对多等映射模式以查询对象来代替.对于为什么要这样呢?"简单就是美",如果你把映射做的太多,太复杂,那学习成本就很高,于是我避开这一环节做了一个NQL强大的查询组件来做为ActiveRecord的助手,使ActiveRecord的概念仍停留在Martin Flowler的定义之中,没有达到完全的ORM目的。林学鹏开发的Grove rm 的思想和我的差不多,只做单表或视图的映射再配合上Oql语言,这在当时是非常火的,因为.NET 平台的一个优点就是短,平,快,果你做的太复杂反而用的就少,比如NHibernate,和Castle框架中的活动记录。至于将来是否支持一对多,多队一,多对多等映射模式,那时后话,有可能会支持的.。

ORM 性能比较(除了数据缓冲机制)

1. 映射比较

OR映射在hibernate和NHibernate中用xml做为映射的,映射的开销是输入输出操作以及DOM对象的解析

Grove的单表映射和Castle中的活动记录是用标签做映射,映射的开销是通过反射读取标签信息来得到映射信息

NDO 的ActiverRocord 或NQL通过直接读取数据库表的元数据做映射,映射开销是读数据库得到元数据。(注:这种方式说白了根本不叫映射,具体原因后面或做介绍)

通过读取元数据来看NDO 的ActiverRocord 或NQL的映射开销比较大。

2.对象的加载以及sql的动态生成

  当今流行的ORM框架,无论是以xml配置做映射还是标签做映射都需要通过反射来加载对象的数据,通过反射来动态生成sql.。

在这方面ActionPack 框架,Ruby on rails 或许我对rails理解有误)方面做的比较好,NDO 的ActiverRocord 就吸收了这两者的思

想,无论在数据的加载或sql的动态生成方面就没有任何反射开销,性能就相应的高了很多!

例子:下面的例子都是以Sql Server2000中的默认数据库Northwind为例

NDO中的活动记录支持三种类型,一种是弱类型,另外一种是强类型,第三种是强类型和弱类型之间,只有强类型的活动记录才能够完全支持从数据库中得到实体对象的IList集合,其它两种只支持返回DataTable,DataSet,DataReader等结果集对象

1。弱类型的例子:

   1.1数据加载Load ,或LoadByKey返回数据库中的一条记录,如果有多条只加载第一条记录

None.gif ActiveRecord product  =   new  ActiveRecord( " Products " );
None.gifproduct.LoadByKey(
1 );
None.gif
this .Text  =  ( string )product[ " ProductName " +   " -------- "   +  product[ " SupplierID " ];

SQL  输出

None.gif SELECT  
None.gif    
[ ProductID ] ,
None.gif    
[ ProductName ] ,
None.gif    
[ SupplierID ] ,
None.gif    
[ CategoryID ] ,
None.gif    
[ QuantityPerUnit ] ,
None.gif    
[ UnitPrice ] ,
None.gif    
[ UnitsInStock ] ,
None.gif    
[ UnitsOnOrder ] ,
None.gif    
[ ReorderLevel ] ,
None.gif    
[ Discontinued ]
None.gif
FROM
None.gif    
[ Products ]     
None.gif
WHERE
None.gif    
[ ProductID ]    =  @ProductID

1.1数据加载 2

None.gif ActiveRecord product  =   new  ActiveRecord( " Products " );
None.gifproduct.ID 
=   1 ;
None.gifproduct.Load();
None.gif
this .Text  =  ( string )product[ " ProductName " +   " -------- "   +  product[ " SupplierID " ];

SQL  输出同上

1.1 数据加载3 返回了多条记录但是只加载了一条

None.gif ActiveRecord product  =   new  ActiveRecord( " Products " );
    product.SetValue(
" SupplierID ",7 );
None.gifproduct.Load();
None.gif 
this .Text  =  ( string )product[ " ProductName " +   " -------- "   +  product[ " SupplierID " ];

SQL 输出

None.gif SELECT  
None.gif    
[ ProductID ] ,
None.gif    
[ ProductName ] ,
None.gif    
[ SupplierID ] ,
None.gif    
[ CategoryID ] ,
None.gif    
[ QuantityPerUnit ] ,
None.gif    
[ UnitPrice ] ,
None.gif    
[ UnitsInStock ] ,
None.gif    
[ UnitsOnOrder ] ,
None.gif    
[ ReorderLevel ] ,
None.gif    
[ Discontinued ]
None.gif
FROM
None.gif    
[ Products ]
None.gif
WHERE
None.gif    
[ SupplierID ] = @SupplierID

1.2 数据查询(返回零条或多条记录,这个类似与Quey对象的用法,活动记录里面封装了CRUD的四个查询对象方便用户更灵活的操作数据库)

None.gif ActiveRecord product  =   new  ActiveRecord( " Products " );
None.gif
this .dataGrid1.DataSource  =  product
None.gif                .SelectCommand
None.gif                .NewWhere(
" SupplierID " , 7 )
None.gif                .And(
" CategoryID " , 3 )
None.gif                .GetDataTable();

SQL 输出

None.gif SELECT  
None.gif    
[ ProductID ] ,
None.gif    
[ ProductName ] ,
None.gif    
[ SupplierID ] ,
None.gif    
[ CategoryID ] ,
None.gif    
[ QuantityPerUnit ] ,
None.gif    
[ UnitPrice ] ,
None.gif    
[ UnitsInStock ] ,
None.gif    
[ UnitsOnOrder ] ,
None.gif    
[ ReorderLevel ] ,
None.gif    
[ Discontinued ]
None.gif
FROM
None.gif    
[ Products ]     
None.gif
WHERE
None.gif    
[ SupplierID ]    =  @SupplierID
None.gif    
AND   [ CategoryID ]    =  @CategoryID

1.3 数据插入操作

None.gif ActiveRecord rg  =   new  ActiveRecord( " Region " );
None.gifrg.ID 
=   6 ;
None.gifrg[
" RegionDescription " =  "66" ;           
    rg.Save();

SQL  输出

None.gif INSERT   INTO   [ Region ]  (
None.gif    
[ RegionID ] ,
None.gif    
[ RegionDescription ]
None.gif
VALUES  (
None.gif    @RegionID,
None.gif    @RegionDescription
None.gif)

1.4数据更新

None.gif ActiveRecord rg  =   new  ActiveRecord( " Region " );
None.gifrg.ID 
=   6 ;
    rg.Load();
None.gifrg[
" RegionDescription " =  "66666" ;           
    rg.Save();

SQL 输出

None.gif SELECT  
None.gif    
[ RegionID ] ,
None.gif    
[ RegionDescription ]
None.gif
FROM
None.gif    
[ Region ]
None.gif
WHERE
None.gif    
[ RegionID ] = @RegionID
None.gif
None.gif
UPDATE   [ Region ]   SET  
None.gif    
[ RegionDescription ]   =  @RegionDescription
None.gif
WHERE
None.gif    RegionID 
=  @RegionID

1.5 数据删除

None.gif ActiveRecord rg  =   new ActiveRecord( " Region " );
None.gifrg.ID
= 6 ;
None.gifrg.Delete();

SQL  输出

None.gif DELETE   FROM   [ Region ]
None.gif
WHERE
None.gif    RegionID 
=  @RegionID

1.5 数据删除2(条件删除(活动记录里面封装了Table数据库表的元数据对象里面),也可以以Filter方式进行删除或Where子句的方式进行删除)

None.gif ActiveRecord rg  =   new ActiveRecord( " Region " ); None.gif           
   Condition con  =  rg.DeleteCommand.NewCondition(rg.Table.Key.Columns[ 0 ].Name)  ==   6 ;
None.gifcon.Execute();
None.gif

SQL  输出同上

上一篇   下一篇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值