Castle ActiveRecord学习实践(5):实现Many–Many关系的映射

简介:
摘要:多对多的关系在日常开发中也会经常遇到,在 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

 )
 
二.编写实体类代码
为了实现多对多的关系,我们要在 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
指明哪些操作会从父对象级联到关联的对象,相关的操作见后面,如果不指定,则为None
Cascade=ManyRelationCascadeEnum.All
Inverse
指定是否级联操作
Inverse =true|false
Schema
指定Schema的名字
Schema="ARDemo"
Table
指定持久化类所关联的数据库表名,如果表名与类名相同,可以省略
Table="posts"
ColumnKey
本实体类于另一个实体类关联的外键
ColumnKey="community_id"
ColumnRef
另一实体类的外键
ColumnRef="blog_id"
Where
指定一个附加SQLWhere子句
Where="IsPost = 0"
Lazy
指定是否延迟加载关联对象
Lazy=true|false
 
Cascade 的类型值有如下几种
类型
说明
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,让它同时属于好几个社区
[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 .级联更新:对一个已经存在Blog,更改它属于更多的社区
[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子句。













本文转自lihuijun51CTO博客,原文链接:  http://blog.51cto.com/terrylee/67662 ,如需转载请自行联系原作者

相关文章
|
8月前
|
Java
java面向对象高级分层实例_实体类
java面向对象高级分层实例_实体类
|
存储 SQL Java
hibernate学习笔记之二(映射关系与懒加载)
hibernate学习笔记之二(映射关系与懒加载)
hibernate学习笔记之二(映射关系与懒加载)
|
SQL Java 数据库连接
Hibernate【映射】知识要点(三)
Hibernate【映射】知识要点
124 0
Hibernate【映射】知识要点(三)
|
Java 数据库连接 数据库
Hibernate【映射】知识要点(四)
Hibernate【映射】知识要点
133 0
Hibernate【映射】知识要点(四)
|
Java 数据库连接 数据库
Hibernate【映射】知识要点(一)
Hibernate【映射】知识要点
123 0
Hibernate【映射】知识要点(一)
|
SQL Java 数据库连接
Hibernate【映射】知识要点(二)
Hibernate【映射】知识要点
150 0
Hibernate【映射】知识要点(二)
|
XML Java 数据库连接
Hibernate【映射】知识要点
前言 前面的我们使用的是一个表的操作,但我们实际的开发中不可能只使用一个表的...因此,本博文主要讲解关联映射 集合映射 需求分析:当用户购买商品,用户可能有多个地址。 数据库表 我们一般如下图一样设计数据库表,一般我们不会在User表设计多个列来保存地址的。
1028 0

热门文章

最新文章