ActiveRecord学习(三):映射

本文深入介绍了AR实体类与数据库之间的映射原理,包括Class、PrimaryKey、Property等基本映射属性,以及BelongsTo、HasMany、HasAndBelongsToMany等高级关系映射,并提供了详细的代码示例。
      AR实体类与数据库之间的映射是通过Attributes来实现的,本文将介绍如何在AR中创建与数据库之间的映射实体,以及几种常见映射关系的实现.关于映射基础部分参考了Castle的官方网站: http://www.castleproject.org/index.php/ActiveRecord:Mappings
本文只介绍和后面例子相关的Attributes,每种映射Attribute的详细属性的说明请参考TerryLee的文章: http://terrylee.cnblogs.com/archive/2006/04/06/367978.html  .

第一部分、映射基础
1、Class
     这个一看就知道是定义一个类,AR规定每个AR实体类必须继承ActiveRecordBase类,并且要使用ActiveRecordAttribute.如下:
None.gif using  System;
None.gif
using  Castle.ActiveRecord;
None.gif
None.gif[ActiveRecord(
" Companies " )]
None.gif
public  Class Company : ActiveRecordBase
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif  
ExpandedBlockEnd.gif}
上面的代码就定义了一个AR实体,ActiveRecord特性就代表该类对应数据库中的哪张表,如果类名和表明相同,那么可以省略不写
None.gif [ActiveRecord()]
None.gif
public   class  Companies : ActiveRecordBase
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedBlockEnd.gif}

None.gif

2、PrimaryKey(声明主键)
None.gif private   int  _id;
None.gif[PrimaryKey]
None.gif
public   int  Id
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif   
getdot.gif{return _id;}
ExpandedSubBlockStart.gifContractedSubBlock.gif   
setdot.gif{_id = value;}
ExpandedBlockEnd.gif}

如果数据库中主键的字段名和在AR实体中定义的属性名不同的话,则需指定主键属性对应于数据库中的字段名。
3、Property(特性)
每个Property对应数据库中的一个非主键的字段,和PrimaryKey的用法一样。

None.gif private   string  _cname;
None.gif[Property]
None.gif
public   string  Cname
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
getdot.gif{return _cname;}
ExpandedSubBlockStart.gifContractedSubBlock.gif    
setdot.gif{_cname = value;}
ExpandedBlockEnd.gif}

None.gif


None.gif private   string  _cname;
None.gif[Property(
" companies_Cname " )]
None.gif
public   string  Cname
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
getdot.gif{return _cname;}
ExpandedSubBlockStart.gifContractedSubBlock.gif    
setdot.gif{_cname = value;}
ExpandedBlockEnd.gif}

None.gif

4、BelongsTo(属于),HasMany(包含)
BelongsTo用于描述实体间多对一(Many to One)的关系,HasMany用于描述一对多的实体间关系,例如博客,每个博客可以有多篇文章,文章和博客之间的关系就是多对一,反之博客和文章之间的关系就是一对多。
Many To One:

None.gif [ActiveRecord]
None.gif
public   class  Post : ActiveRecordBase
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private Blog blog;
InBlock.gif
InBlock.gif    [BelongsTo(
"post_blogid")]
InBlock.gif    
public Blog Blog
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn blog; }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ blog = value; }
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

One To Many:

None.gif [ActiveRecord( " Blogs " )]
None.gif
public   class  Blog : ActiveRecordBase
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private IList _posts;
InBlock.gif
InBlock.gif    [HasMany(
typeof(Post), Table="posts", ColumnKey="post_blogid")]
InBlock.gif    
public IList Posts
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _posts; }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ _posts = value; }
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

HasMany 特性中必须指明子表的名称,以及关联的外键字段名。

5、HasAndBelongsToMany
此特性用于描述实体间多对多(Many To Many)的关系。随着企业的集团化,企业中员工和部门之间的关系就是一个典型的Many To Many关系,一个部门可以有多个员工,一个员工可以属于几个部门。我们在做企业组织机构的时候首先要建企业部门和企业员工这两个对象表,然后这两张表之间的联系通过另外一张表来描述,这个表称为关系表。
描述多对多关系是需注意几个必须指定的属性:
Table:用于指定描述两个对象表之间关系的表名。
ColumnRef:关联于另外一个对象表的字段名,这个字段名是关系表中的。
ColumnKey:关系表中对应自己的字段名

None.gif [HasAndBelongsToMany( typeof (AR.Model.People),Table = " people_companies " ,ColumnRef = " people_id " , ColumnKey = " company_id "  )]
None.gif        
public  IList People
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif            
getdot.gif{return _people;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
setdot.gif{_people = value;}
ExpandedBlockEnd.gif        }
None.gif [HasAndBelongsToMany(  typeof (Company), 
None.gif             Table
= " people_companies "
None.gif             ColumnRef
= " company_id " , ColumnKey = " people_id "  )]
None.gif        
public  IList Companies
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifreturn _companies; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{ _companies = value; }
ExpandedBlockEnd.gif        }

第二部分、各种映射关系的操作
这几种操作,TerryLee的博客中已经写的很清楚了,我就不再多说了,我只讲一个Many To Many的关系,因为当时我按照TerryLee的博客上写的做调试没通过,后来自己重做的。

TerryLee的文章: http://terrylee.cnblogs.com/archive/2006/04/06/368471.html

Many To Many:
1、数据库
None.gif -- 1.部门表
None.gif
create   table  companies
None.gif(
None.gif    id            
int   identity ,
None.gif    pid            
int              null ,    
None.gif    cname        
varchar ( 50 )             null ,
None.gif    type        
varchar ( 20 )             null ,
None.gif    
primary   key (id)
None.gif)
None.gif
go
None.gif
None.gif
-- 2.员工表
None.gif
create   table  people
None.gif(
None.gif    id            
int   identity ,
None.gif    pname        
varchar ( 20 )         null ,
None.gif    
primary   key (id)
None.gif)
None.gif
go
None.gif
None.gif
-- 3.部门员工对照表
None.gif
create   table  people_companies
None.gif(
None.gif    people_id        
int              not   null ,
None.gif    company_id        
int              not   null
None.gif)
None.gif
go

2、创建AR实体
ContractedBlock.gif ExpandedBlockStart.gif Company
None.gifusing System;
None.gif
using System.Collections;
None.gif
using Castle.ActiveRecord;
None.gif
using Castle.ActiveRecord.Queries;
None.gif
None.gif
namespace AR.Model
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// Company 的摘要说明。
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    [ActiveRecord("companies")]
InBlock.gif    
public class Company : Castle.ActiveRecord.ActiveRecordBase
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private int _id;
InBlock.gif        
private int _pid;
InBlock.gif        
private string _cname;
InBlock.gif        
private string _type;
InBlock.gif
InBlock.gif        
private IList _people;
InBlock.gif
InBlock.gif        
public Company()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public Company(string name)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this._cname = name;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        [PrimaryKey]
InBlock.gif        
public int Id
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
getdot.gif{return _id;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
setdot.gif{_id = value;}
ExpandedSubBlockEnd.gif        }

InBlock.gif    
InBlock.gif        [Property]
InBlock.gif        
public int Pid
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
getdot.gif{return _pid;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
setdot.gif{_pid = value;}
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        [Property]
InBlock.gif        
public string Cname
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
getdot.gif{return _cname;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
setdot.gif{_cname = value;}
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        [Property]
InBlock.gif        
public string Type
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
getdot.gif{return _type;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
setdot.gif{_type = value;}
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        [HasAndBelongsToMany(
typeof(AR.Model.People),Table="people_companies",ColumnRef="people_id", ColumnKey="company_id" )]
InBlock.gif        
public IList People
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
getdot.gif{return _people;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
setdot.gif{_people = value;}
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public static void DeleteAll()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            ActiveRecordBase.DeleteAll(
typeof(Company));
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static Company[] FindAll()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return ((Company[])(ActiveRecordBase.FindAll(typeof(Company))));
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static Company Find(int id)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return ((Company)(ActiveRecordBase.FindByPrimaryKey(typeof(Company), id)));
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

ContractedBlock.gif ExpandedBlockStart.gif People
None.gifusing System;
None.gif
using System.Collections;
None.gif
using Castle.ActiveRecord;
None.gif
None.gif
namespace AR.Model
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// People 的摘要说明。
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    [ActiveRecord("people")]
InBlock.gif    
public class People : ActiveRecordBase
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private int _id;
InBlock.gif        
private String _name;
InBlock.gif        
private IList _companies;
InBlock.gif
InBlock.gif        
public People()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            _companies 
= new ArrayList();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        [PrimaryKey]
InBlock.gif        
public int Id
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifreturn _id; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{ _id = value; }
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        [Property(
"pname")]
InBlock.gif        
public string Name
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifreturn _name; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{ _name = value; }
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        [HasAndBelongsToMany( 
typeof(Company), 
InBlock.gif             Table
="people_companies"
InBlock.gif             ColumnRef
="company_id", ColumnKey="people_id" )]
InBlock.gif        
public IList Companies
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifreturn _companies; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{ _companies = value; }
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public static void DeleteAll()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            ActiveRecordBase.DeleteAll(
typeof(People));
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static People[] FindAll()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return ((People[])(ActiveRecordBase.FindAll(typeof(People))));
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static People Find(int id)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return ((People)(ActiveRecordBase.FindByPrimaryKey(typeof(People), id)));
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}

3、ADD Of Many To Many
None.gif // 添加
None.gif
         private   void  Button1_Click( object  sender, System.EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
//新增一个员工,让他同时属于两个部门
InBlock.gif
            People per = new People();
InBlock.gif            per.Name 
= "pw";
InBlock.gif
InBlock.gif            ArrayList al 
= new ArrayList();
InBlock.gif
InBlock.gif            al.Add(Company.Find(
2));
InBlock.gif            al.Add(Company.Find(
3));
InBlock.gif
InBlock.gif            per.Companies 
= al;
InBlock.gif
InBlock.gif            per.Save();
ExpandedBlockEnd.gif        }

None.gif

4、Update of Many To Many
None.gif // 更新
None.gif
         private   void  Update_Click( object  sender, System.EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
//查找一个已经存在的员工,更新他所在的部门
InBlock.gif
            People per = People.Find(1);
InBlock.gif            
//删除他以前所在的部门再添加,如果不删除以前的部门,就把下面第一句去掉
InBlock.gif
            per.Companies.Clear();
InBlock.gif
InBlock.gif            per.Companies.Add(Company.Find(
6));
InBlock.gif            per.Companies.Add(Company.Find(
7));
InBlock.gif
InBlock.gif            per.Save();
ExpandedBlockEnd.gif        }

5、Delete of Many To Many
None.gif // 删除
None.gif
         private   void  Delete_Click( object  sender, System.EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
//此时只删除了People表和companies_people表的相应的纪录,因Company表的纪录还可能跟其他的纪录有关联,所以不能删除
InBlock.gif            
//如果只是想删除员工和部门的对应关系,可以用per.clear();或per.Remove();
InBlock.gif
            People per = People.Find(1);
InBlock.gif
InBlock.gif            
using(TransactionScope trans = new TransactionScope())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
try
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    per.Delete();
InBlock.gif
InBlock.gif                    trans.VoteCommit();
ExpandedSubBlockEnd.gif                }

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

ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

 

关于AR的映射及其基本操作就说到这里,这里再次感谢TerryLee,他的文章对我帮助很大,同时很渴望和对AR有兴趣的朋友多多交流.
前两篇:
(一):http://pw.cnblogs.com/archive/2006/05/20/405131.aspx
(二):http://www.cnblogs.com/pw/archive/2006/05/21/405517.html

转载于:https://www.cnblogs.com/pw/archive/2006/05/21/405825.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值