Castle ActiveRecord学习实践(5):实现Many–Many关系的映射
2007-07-03 09:31
627 查看
摘要:多对多的关系在日常开发中也会经常遇到,在ActiveRecord中我们用HasAndBelongsToMany特性来实现Many-Many的关联,本文将通过一个具体的实例来介绍这一用法。
主要内容
1.准备数据库表
2.编写实体类
3.编写测试代码
一.准备数据库表
接着在上篇文章中的例子,为了实现多对多的关系,我们引入Community,即每个Blog可以属于多个社区,每个社区也可以有多个Blog。
CREATE TABLE Blogs (
blog_id int IDENTITY(1, 1) PRIMARY KEY,
blog_name varchar(50),
blog_author varchar(50)
)
CREATE TABLE Blog_Community (
blog_Id int NOT NULL ,
community_Id int NOT NULL
)
CREATE TABLE Communities (
community_Id int IDENTITY (1, 1) PRIMARY KEY,
community_Name varchar (50) ,
community_Intro varchar (500)
)
[align=left] [/align]
二.编写实体类代码
为了实现多对多的关系,我们要在Blog、Community类中分别使用HasAndBelongsToMany特性,不需要编写Blog_Community类。示例代码:
的参数相信大家都能够看明白,指定关联表名和关联的外键就可以了。
//
Blog
[HasAndBelongsToMany( typeof(Community),
Table="Blog_Community",
ColumnRef=" community_id ",
ColumnKey=" blog_id " )]
public IList Communitys
{
get
{ return _community; }
set
{ _ community = value; }
}
//
Community
[HasAndBelongsToMany( typeof(Blog),
Table="Blog_Community",
ColumnRef="blog_id",
ColumnKey="community_id" )]
public IList Blogs
{
get
{ return _blog; }
set
{ _ blog = value; }
}
HasAndBelongsToMany
注意:这三个参数必须指定,不可以省略!
HasManyAttribute说明
Cascade的类型值有如下几种
最后完整的实体类如下:
/**//// <summary>
/// Blog 的摘要说明。
/// </summary>
[ActiveRecord("Blogs")]
public class Blog : ActiveRecordBase
{
private int _id;
private String _name;
private String _author;
private IList _community;
[PrimaryKey(PrimaryKeyType.Identity, "blog_id")]
public int Id
{
get
{ return _id; }
set
{ _id = value; }
}
[Property("blog_name")]
public String Name
{
get
{ return _name; }
set
{ _name = value; }
}
[Property("blog_author")]
public String Author
{
get
{ return _author; }
set
{ _author = value; }
}
[HasAndBelongsToMany(typeof(Community),
Table="Blog_Community",
ColumnRef=" community_id ",
ColumnKey=" blog_id " )]
public IList Communities
{
get
{ return _community; }
set
{ _community = value; }
}
public static void DeleteAll()
{
DeleteAll( typeof(Blog) );
}
public static Blog[] FindAll()
{
return (Blog[]) FindAll( typeof(Blog) );
}
public static Blog Find(int id)
{
return (Blog) FindByPrimaryKey( typeof(Blog), id );
}
}
/**//// <summary>
/// Community 的摘要说明。
/// </summary>
[ActiveRecord("Communities")]
public class Community : ActiveRecordBase
{
private int _id;
private String _name;
private String _intro;
private IList _blog;
[PrimaryKey(PrimaryKeyType.Identity, "Community_Id")]
public int Id
{
get
{ return _id; }
set
{ _id = value; }
}
[Property("Community_Name")]
public String Name
{
get
{ return _name; }
set
{ _name = value; }
}
[Property("Community_Intro")]
public String Author
{
get
{ return _intro; }
set
{ _intro = value; }
}
[HasAndBelongsToMany(typeof(Blog),
Table="Blog_Community",
ColumnRef="blog_id",
ColumnKey="community_id" )]
public IList Blogs
{
get
{ return _blog; }
set
{ _blog = value; }
}
public static void DeleteAll()
{
DeleteAll( typeof(Community) );
}
public static Community[] FindAll()
{
return (Community[]) FindAll( typeof(Community) );
}
public static Community Find(int id)
{
return (Community) FindByPrimaryKey( typeof(Community), id );
}
}
三.编写测试代码
下面是我写的一些简单的测试代码,有兴趣的可以看一下。
1.级联增加:新增一个Blog,让它同时属于好几个社区
.级联更新:对一个已经存在Blog,更改它属于更多的社区
[Test]
public void TestCascadingSave()
{
//新建一个Blog
Blog blog = new Blog();
blog.Name = "Tech Space";
blog.Author = "Terrylee";
//属于ID为1,2社区
ArrayList list = new ArrayList();
list.Add(Community.Find(1));
list.Add(Community.Find(2));
blog.Communities = list;
//保存
blog.Save();
}
2
[Test]
public void TestCascadingUpdate()
{
//测试1:查找一个Blog
Blog blog = Blog.Find(10);
IList clist = blog.Communities;
clist.Add(Community.Find(4));
clist.Add(Community.Find(3));
blog.Save();
//测试2:查找一个Community
Community community = Community.Find(3);
IList blist = community.Blogs;
blist.Add(Blog.Find(8));
community.Save();
}
3.级联删除:删除一个Blog,级联表中对应的记录应该删除,但Community不能删除,因为还有别的Blog和它关联
[Test]
public void TestCascadingDelete()
{
//测试1:删除Blog
Blog blog = Blog.Find(10);
using(TransactionScope btran = new TransactionScope())
{
try
{
blog.Delete();
btran.VoteCommit();
}
catch
{
btran.VoteRollBack();
}
}
//测试2:删除Community
Community community = Community.Find(3);
using(TransactionScope ctran = new TransactionScope())
{
try
{
community.Delete();
ctran.VoteCommit();
}
catch
{
ctran.VoteRollBack();
}
}
}
好了,关于Many-Many关联映射就写这么多了,内容比较简单。下篇文章我会介绍在ActiveRecord中实现延迟加载和使用Where子句。
参考资料
Castle的官方网站http://www.castleproject.org
主要内容
1.准备数据库表
2.编写实体类
3.编写测试代码
一.准备数据库表
接着在上篇文章中的例子,为了实现多对多的关系,我们引入Community,即每个Blog可以属于多个社区,每个社区也可以有多个Blog。
CREATE TABLE Blogs (
blog_id int IDENTITY(1, 1) PRIMARY KEY,
blog_name varchar(50),
blog_author varchar(50)
)
CREATE TABLE Blog_Community (
blog_Id int NOT NULL ,
community_Id int NOT NULL
)
CREATE TABLE Communities (
community_Id int IDENTITY (1, 1) PRIMARY KEY,
community_Name varchar (50) ,
community_Intro varchar (500)
)
[align=left] [/align]
二.编写实体类代码
为了实现多对多的关系,我们要在Blog、Community类中分别使用HasAndBelongsToMany特性,不需要编写Blog_Community类。示例代码:
的参数相信大家都能够看明白,指定关联表名和关联的外键就可以了。
//
Blog
[HasAndBelongsToMany( typeof(Community),
Table="Blog_Community",
ColumnRef=" community_id ",
ColumnKey=" blog_id " )]
public IList Communitys
{
get
{ return _community; }
set
{ _ community = value; }
}
//
Community
[HasAndBelongsToMany( typeof(Blog),
Table="Blog_Community",
ColumnRef="blog_id",
ColumnKey="community_id" )]
public IList Blogs
{
get
{ return _blog; }
set
{ _ blog = value; }
}
HasAndBelongsToMany
注意:这三个参数必须指定,不可以省略!
HasManyAttribute说明
[align=center]属性[/align] | [align=center]说明[/align] | [align=center]示例[/align] |
Cascade | 指明哪些操作会从父对象级联到关联的对象,相关的操作见后面,如果不指定,则为None | Cascade=ManyRelationCascadeEnum.All |
Inverse | 指定是否级联操作 | Inverse =true|false |
Schema | 指定Schema的名字 | Schema="ARDemo" |
Table | 指定持久化类所关联的数据库表名,如果表名与类名相同,可以省略 | Table="posts" |
ColumnKey | 本实体类于另一个实体类关联的外键 | ColumnKey="community_id" |
ColumnRef | 另一实体类的外键 | ColumnRef="blog_id" |
Where | 指定一个附加SQL的Where子句 | Where="IsPost = 0" |
Lazy | 指定是否延迟加载关联对象 | Lazy=true|false |
[align=center]类型[/align] | [align=center]说明[/align] |
None | 不进行级联操作 |
SaveUpdate | 进行级联Save/Update操作 |
Delete | 进行级联Delete操作 |
All | 进行级联Save/Update/Delete操作 |
AllDeleteOrphan | 进行级联Save/Update/Delete操作,并删除无相关父对象的子对象 |
/**//// <summary>
/// Blog 的摘要说明。
/// </summary>
[ActiveRecord("Blogs")]
public class Blog : ActiveRecordBase
{
private int _id;
private String _name;
private String _author;
private IList _community;
[PrimaryKey(PrimaryKeyType.Identity, "blog_id")]
public int Id
{
get
{ return _id; }
set
{ _id = value; }
}
[Property("blog_name")]
public String Name
{
get
{ return _name; }
set
{ _name = value; }
}
[Property("blog_author")]
public String Author
{
get
{ return _author; }
set
{ _author = value; }
}
[HasAndBelongsToMany(typeof(Community),
Table="Blog_Community",
ColumnRef=" community_id ",
ColumnKey=" blog_id " )]
public IList Communities
{
get
{ return _community; }
set
{ _community = value; }
}
public static void DeleteAll()
{
DeleteAll( typeof(Blog) );
}
public static Blog[] FindAll()
{
return (Blog[]) FindAll( typeof(Blog) );
}
public static Blog Find(int id)
{
return (Blog) FindByPrimaryKey( typeof(Blog), id );
}
}
/**//// <summary>
/// Community 的摘要说明。
/// </summary>
[ActiveRecord("Communities")]
public class Community : ActiveRecordBase
{
private int _id;
private String _name;
private String _intro;
private IList _blog;
[PrimaryKey(PrimaryKeyType.Identity, "Community_Id")]
public int Id
{
get
{ return _id; }
set
{ _id = value; }
}
[Property("Community_Name")]
public String Name
{
get
{ return _name; }
set
{ _name = value; }
}
[Property("Community_Intro")]
public String Author
{
get
{ return _intro; }
set
{ _intro = value; }
}
[HasAndBelongsToMany(typeof(Blog),
Table="Blog_Community",
ColumnRef="blog_id",
ColumnKey="community_id" )]
public IList Blogs
{
get
{ return _blog; }
set
{ _blog = value; }
}
public static void DeleteAll()
{
DeleteAll( typeof(Community) );
}
public static Community[] FindAll()
{
return (Community[]) FindAll( typeof(Community) );
}
public static Community Find(int id)
{
return (Community) FindByPrimaryKey( typeof(Community), id );
}
}
三.编写测试代码
下面是我写的一些简单的测试代码,有兴趣的可以看一下。
1.级联增加:新增一个Blog,让它同时属于好几个社区
.级联更新:对一个已经存在Blog,更改它属于更多的社区
[Test]
public void TestCascadingSave()
{
//新建一个Blog
Blog blog = new Blog();
blog.Name = "Tech Space";
blog.Author = "Terrylee";
//属于ID为1,2社区
ArrayList list = new ArrayList();
list.Add(Community.Find(1));
list.Add(Community.Find(2));
blog.Communities = list;
//保存
blog.Save();
}
2
[Test]
public void TestCascadingUpdate()
{
//测试1:查找一个Blog
Blog blog = Blog.Find(10);
IList clist = blog.Communities;
clist.Add(Community.Find(4));
clist.Add(Community.Find(3));
blog.Save();
//测试2:查找一个Community
Community community = Community.Find(3);
IList blist = community.Blogs;
blist.Add(Blog.Find(8));
community.Save();
}
3.级联删除:删除一个Blog,级联表中对应的记录应该删除,但Community不能删除,因为还有别的Blog和它关联
[Test]
public void TestCascadingDelete()
{
//测试1:删除Blog
Blog blog = Blog.Find(10);
using(TransactionScope btran = new TransactionScope())
{
try
{
blog.Delete();
btran.VoteCommit();
}
catch
{
btran.VoteRollBack();
}
}
//测试2:删除Community
Community community = Community.Find(3);
using(TransactionScope ctran = new TransactionScope())
{
try
{
community.Delete();
ctran.VoteCommit();
}
catch
{
ctran.VoteRollBack();
}
}
}
好了,关于Many-Many关联映射就写这么多了,内容比较简单。下篇文章我会介绍在ActiveRecord中实现延迟加载和使用Where子句。
参考资料
Castle的官方网站http://www.castleproject.org
相关文章推荐
- Castle ActiveRecord学习实践(4):实现One-Many关系的映射
- Castle ActiveRecord学习实践(4):实现One-Many关系的映射
- Castle ActiveRecord学习实践(4):实现One-Many关系的映射
- C#.Net Castle ActiveRecord学习实践(4):实现One-Many关系的映射
- C#.Net Castle ActiveRecord学习实践(5):实现Many–Many关系的映射
- Castle ActiveRecord学习实践(4):实现One-Many关系的映射
- Castle ActiveRecord学习实践(5):实现Many–Many关系的映射
- Castle ActiveRecord学习实践(5):实现Many–Many关系的映射
- C#.Net Castle ActiveRecord学习实践(3):映射基础
- Castle ActiveRecord学习实践(9):数据有效性的验证
- 基于Castle ActiveRecord开发Domain Model详解(一)对象关系到数据表的映射
- Castle ActiveRecord学习实践(4)关系映射
- Castle ActiveRecord学习实践(6):延迟加载和使用Where子句
- C#.Net Castle ActiveRecord学习实践(7):使用HQL查询
- C#.Net Castle ActiveRecord学习实践(1):快速入门指南
- C#.Net Castle ActiveRecord学习实践(8):数据有效性的验证
- Castle ActiveRecord学习实践(2):构建配置信息
- Castle ActiveRecord学习实践(6):延迟加载和使用Where子句
- Castle ActiveRecord学习实践(8):数据有效性的验证
- C#.Net Castle ActiveRecord学习实践(2):构建配置信息