程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Castle ActiveRecord學習實踐(5) 實現Many–Many關系的映射

Castle ActiveRecord學習實踐(5) 實現Many–Many關系的映射

編輯:關於.NET

主要內容

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關聯映射就寫這麼多了,內容比較簡單。下篇文章我會介紹在ActiveRecord中實現延遲加載和使用Where子句。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved