Castle-Active Record之使用篇

    前段时间下载了castle的active record(AR)进行试用,通过几天的研究使用,有些心得,现进行一下整理,将所学,所得,所惑都理一下,以待在以后能更好的学习研究.
    本文主要内容:Castle-AR的基本使用,通过一个小小的例子,做到能熟练的使用AR,对AR有一个感性的认识,在以后空余时间能对其进行深入的研究,学习.
    话不多说,进入主题,ORM的概念博客园上已经介绍得很多,这里就不再提及.先介绍一下例子,这是我自己想的一个环境,包括如下对象:Blog(博客),Post(随笔),PostType(随笔类型),Community(社区),之所以虚构这几个对象,主要是想考察AR对各种关系的表现能力,和处理容易度,而这几个对象之间可以包括数据库中常见的一对多(Blog和Post的关系),多对一(Post和PostType的关系),多对多的关系(Blog和Community的关系),一对一的关系暂不考虑.库的结构如下图所示:
%E6%9C%AA%E5%91%BD%E5%90%8D.jpg
生成数据库的脚本如下:

ContractedBlock.gif ExpandedBlockStart.gif Sql #region Sql
InBlock.gifCREATE TABLE [dbo].[Blog] (
InBlock.gif    [BlogId] [
int] IDENTITY (11) NOT NULL ,
InBlock.gif    [BlogName] [varchar] (
50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
InBlock.gif    [BlogIntro] [varchar] (
100) COLLATE Chinese_PRC_CI_AS NULL ,
InBlock.gif    [Email] [varchar] (
50) COLLATE Chinese_PRC_CI_AS NULL ,
InBlock.gif    [RegistTime] [datetime] NULL 
InBlock.gif) ON [PRIMARY]
InBlock.gifGO
InBlock.gif
InBlock.gifCREATE TABLE [dbo].[Blog_Community] (
InBlock.gif    [BlogId] [
int] NOT NULL ,
InBlock.gif    [CommunityId] [
int] NOT NULL 
InBlock.gif) ON [PRIMARY]
InBlock.gifGO
InBlock.gif
InBlock.gifCREATE TABLE [dbo].[Community] (
InBlock.gif    [CommunityId] [
int] IDENTITY (11) NOT NULL ,
InBlock.gif    [CommunityName] [varchar] (
50) COLLATE Chinese_PRC_CI_AS NULL ,
InBlock.gif    [CommunityIntro] [varchar] (
500) COLLATE Chinese_PRC_CI_AS NULL 
InBlock.gif) ON [PRIMARY]
InBlock.gifGO
InBlock.gif
InBlock.gifCREATE TABLE [dbo].[Post] (
InBlock.gif    [PostId] [
int] IDENTITY (11) NOT NULL ,
InBlock.gif    [PostTypeId] [
int] NULL ,
InBlock.gif    [BlogId] [
int] NULL ,
InBlock.gif    [PostName] [varchar] (
50) COLLATE Chinese_PRC_CI_AS NULL ,
InBlock.gif    [PostContext] [varchar] (
500) COLLATE Chinese_PRC_CI_AS NULL ,
InBlock.gif    [PostTime] [datetime] NULL ,
InBlock.gif    [IsPost] [
char] (10) COLLATE Chinese_PRC_CI_AS NULL 
InBlock.gif) ON [PRIMARY]
InBlock.gifGO
InBlock.gif
InBlock.gifCREATE TABLE [dbo].[PostType] (
InBlock.gif    [PostTypeId] [
int] IDENTITY (11) NOT NULL ,
InBlock.gif    [PostTypeName] [varchar] (
50) COLLATE Chinese_PRC_CI_AS NULL 
InBlock.gif) ON [PRIMARY]
InBlock.gifGO
ExpandedBlockEnd.gif
#endregion
OK,环境搭好了.现在进入我们最关心的部分

1.AR 之 一对多.
在该例子中Blog与Post之间的关系是一对多的.现在我们先来介绍一下由AR Generator自动生成的代码
None.gif [ActiveRecord( " Blog " )]
None.gif
public   class  Blog : ActiveRecordBase
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {dot.gif}
ActiveRecord特性表明该实体类与数据库中的哪张表对应.凡是要通过AR与库中的表进行映射的实体类必须继承ActiveRecordBase类.

None.gif [PrimaryKey(PrimaryKeyType.Native)]
None.gif        
public   int  BlogId
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return this.blogId;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this.blogId = value;
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }
这个地球人一看就明白了吧:)这里因为我属性的名称与库中的字段名称是一样的,所以,不用将该属性映射的字段写出来.非主键的属性可以通过[Property()]特性描述.(怎么样?是不是觉得比Nhibernate的映射文件要简单了许多啊?)

现在到了关键,我们的一对多关系:
None.gif [HasMany( typeof (Post), Table = " Post " , ColumnKey = " BlogId " )]
None.gif        
public  System.Collections.IList Posts
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return this.posts;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this.posts = value;
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

AR采用HasMany来描述这种关系,后面参数的名称想必一看便知,Post是"多"的表名,BlogId是该表的主建.
好,我们再来看看Post类中的关键映射代码:

None.gif [BelongsTo( " BlogId " )]
None.gif        
public  Blog Blog
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return this.blog;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this.blog = value;
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

是不是同样简单呢?

2.AR 之 多对一.
(这就不多讲了,只是HasMany和BelongsTo放的地方不同,关注的方向不同而已,用法都一样)

3.AR之 多对多.
在这个例子中,Blog和Community是多对多的关系.在我们一般的设计中,一般会把多对多的两个表拆成三个表,在这里,我加入了一个表Blog_Community.(该表不需要在AR中进行映射,AR会自动帮你完成相关操作).我们先看一下Blog里面的关键代码:

None.gif [HasAndBelongsToMany( typeof (Community), Table = " Blog_Community " ,ColumnRef = " CommunityId " , ColumnKey = " BlogId " )]
None.gif        
public  System.Collections.IList Community
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return this.community;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this.community = value;
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }
AR使用HasAndBelongsToMany来表示多对多的关系.其他参数我想各位一看便知道,不多费话.再看看Community里面的关键代码:
None.gif [HasAndBelongsToMany( typeof (Blog), Table = " Blog_Community " ,ColumnRef = " BlogId " , ColumnKey = " CommunityId " )]
None.gif        
public  System.Collections.IList Blog
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return this.blog;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this.blog = value;
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }
OK.这就完成了AR中的多对多的映射关系.(注意一点:我在生成各实体类的代码的时候,是使用的AR带的一个AR Generator,在将Blog表选进去的时候,他把Blog_Community和Community表都导进去了,从而生成的是一个一对多的关系和一个多对一个关系,所以后来我手动修改的代码添加了HasAndBelongsToMany的特性,不知道这是否是AR Generetor的一个BUG).

OK.这三种关系的映射就先介绍到这,以下是我写的一些测试代码.感兴趣的可以瞄两眼.
None.gif [Test]
None.gif        
public   void  TestBlogCRUD()
ContractedBlock.gifExpandedBlockStart.gif        
dot.gif {
InBlock.gif            Blog b 
= new Blog();
InBlock.gif            b.BlogName 
= "DotNetFresh";
InBlock.gif            b.BlogIntro 
= "StudyDotNet";
InBlock.gif            b.Email 
= "hello@163.com";
InBlock.gif            b.RegistTime 
= DateTime.Now;
InBlock.gif            b.Create();  
//C
InBlock.gif

InBlock.gif            b.BlogIntro 
= "Good good study,day day up";
InBlock.gif            b.Update(); 
//U
InBlock.gif

InBlock.gif            Blog bb 
= Blog.Find(b.BlogId); //R
InBlock.gif
            bb.Delete(); //D
InBlock.gif
            
ExpandedBlockEnd.gif        }
None.gif [Test]
None.gif        
public   void  TestAddBlogWithPostAndPostType()
ContractedBlock.gifExpandedBlockStart.gif        
dot.gif {
InBlock.gif            
//新建一个Blog
InBlock.gif
            Blog b = new Blog();
InBlock.gif            b.BlogName 
= "withpost";
InBlock.gif            b.BlogIntro 
= "i'm have post already";
InBlock.gif            b.Email 
= "hello@163.com";
InBlock.gif            b.RegistTime 
= DateTime.Now;
InBlock.gif
InBlock.gif            
//新建一个PostType
InBlock.gif
            PostType type = new PostType();
InBlock.gif            type.PostTypeName 
= "new type";
InBlock.gif            
InBlock.gif            
//新建一个Post
InBlock.gif
            Post p = new Post();
InBlock.gif            p.Blog 
= b;
InBlock.gif            p.PostType 
= type;
InBlock.gif            p.PostName 
= "new post";
InBlock.gif            p.PostTime 
= DateTime.Now;
InBlock.gif
InBlock.gif            
//执行事务,将上面三个对象持久化到数据库
InBlock.gif
            using(TransactionScope transaction = new TransactionScope())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
try
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    b.Create();
InBlock.gif                    type.Create();
InBlock.gif                    p.Create();
ExpandedSubBlockEnd.gif                }

InBlock.gif                
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    transaction.VoteRollBack();
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

None.gif
None.gif        [Test]
None.gif        
public   void  TestAddBlogWithCommunity()
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
//新建一个Blog
InBlock.gif
            Blog b = new Blog();
InBlock.gif            b.BlogName 
= "withcommunity";
InBlock.gif            b.BlogIntro 
= "i'm in a community already";
InBlock.gif            b.Email 
= "hello@163.com";
InBlock.gif            b.RegistTime 
= DateTime.Now;
InBlock.gif
InBlock.gif            
//该Blog属于的社区
InBlock.gif
            ArrayList al = new ArrayList();
InBlock.gif            al.Add(Community.Find(
3));
InBlock.gif            al.Add(Community.Find(
4));
InBlock.gif            b.Community 
= al;
InBlock.gif
InBlock.gif            b.Create(); 
//保存
ExpandedBlockEnd.gif
        }
好了.不贴了,太多了,从这些代码中同样体现出了幽雅的代码书写方式...好了.剩下的好处各位介绍ORM的说得太多了....;)

总结,心得:Castle的AR底层将NHibernate封装了起来,使用起来感觉比Nhibernate方便多了,不用再去生成一个个的映射文件,调试和维护起来都方便了很多,这应该是使用AR感觉最好的一个地方.另外配合着AR Generator,生成这些代码那叫一个快.不过AR采用反射的方式来处理映射,如果项目大了,不知道会对性能造成多大的影响?另外,经过Castle的这样封装,如果再配合着Castle的容器,一定会发挥更大的威力.继续研究学习吧.....:)

转载于:https://www.cnblogs.com/DotNetFresh/archive/2005/08/05/208256.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值