Castle ActiveRecord学习实践:实现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

指定一个附加SQL的Where子句

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关联映射就写这么多了,内容比较简单。

posted on 2012-11-20 16:36  一个石头  阅读(172)  评论(0)    收藏  举报