zoukankan      html  css  js  c++  java
  • Castle ActiveRecord学习实践(5):实现Many–Many关系的映射

    摘要:多对多的关系在日常开发中也会经常遇到,在ActiveRecord中我们用HasAndBelongsToMany特性来实现Many-Many的关联,本文将通过一个具体的实例来介绍这一用法。

     

    主要内容

    1.准备数据库表

    2.编写实体类

    3.编写测试代码

     

    一.准备数据库表

    接着在上篇文章中的例子,为了实现多对多的关系,我们引入Community,即每个Blog可以属于多个社区,每个社区也可以有多个Blog

    CREATE TABLE Blogs (

        blog_id     
    int IDENTITY(11PRIMARY 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 (11PRIMARY KEY,

         community_Name 
    varchar (50) ,

         community_Intro 
    varchar (500

     )

     

    二.编写实体类代码

    为了实现多对多的关系,我们要在BlogCommunity类中分别使用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子句。

     

    参考资料

    Castle的官方网站http://www.castleproject.org

  • 相关阅读:
    js窗口拖动 模版
    js中准确判断数据类型的方法
    ArcGis Python脚本——批量对影像、要素类定义投影
    ArcGis 属性表.dbf文件使用Excel打开中文乱码的解决方法
    解析ArcGis拓扑——根据拓扑错误记录提取shp文件、导出Excel表格
    解析ArcGis拓扑——检查的流程,以面重叠检查为例
    ArcGis Classic COM Add-Ins插件开发的一般流程 C#
    解析ArcGis的标注(三)——标注的放置 与 转注记修改
    解析ArcGis的标注(二)——认识ArcGis标注标签
    解析ArcGis的标注(一)——先看看分数式、假分数式标注是怎样实现的
  • 原文地址:https://www.cnblogs.com/Terrylee/p/370950.html
Copyright © 2011-2022 走看看