有如下所示表:
CREATE TABLE Posts
(
[id] [int] IDENTITY (1, 1) NOT NULL,
[title] [varchar] (50) NULL,
[contents] [text] NULL
) ON [PRIMARY]
CREATE TABLE Categories
(
[id] [int] IDENTITY (1, 1) NOT NULL,
[title] [varchar] (50) NULL,
) ON [PRIMARY]
CREATE TABLE PostCategory
(
[postid] [int] NOT NULL,
[categoryid] [int] NOT NULL
) ON [PRIMARY]
则Posts类代码应有如下内容:
(
[id] [int] IDENTITY (1, 1) NOT NULL,
[title] [varchar] (50) NULL,
[contents] [text] NULL
) ON [PRIMARY]
CREATE TABLE Categories
(
[id] [int] IDENTITY (1, 1) NOT NULL,
[title] [varchar] (50) NULL,
) ON [PRIMARY]
CREATE TABLE PostCategory
(
[postid] [int] NOT NULL,
[categoryid] [int] NOT NULL
) ON [PRIMARY]
using Castle.ActiveRecord;
[ActiveRecord("posts")]
public class Post : ActiveRecordBase
{
private int id;
private string title;
private string contents;
private Blog blog;
private IList categories = new ArrayList();
[PrimaryKey]
private int Id
{
get { return id; }
set { id = value; }
}
[Property]
public string Title
{
get { return title; }
set { title = value; }
}
[Property(ColumnType="StringClob")]
public string Contents
{
get { return contents; }
set { contents = value; }
}
[BelongsTo("blogid")]
public Blog OwnerBlog
{
get { return blog; }
set { blog = value; }
}
[HasAndBelongsToMany(typeof(Category),
Table="PostCategory", ColumnKey="postid", ColumnRef="categoryid")]
public IList Categories
{
get { return categories; }
set { categories = value; }
}
}
其中
[ActiveRecord("posts")]
public class Post : ActiveRecordBase
{
private int id;
private string title;
private string contents;
private Blog blog;
private IList categories = new ArrayList();
[PrimaryKey]
private int Id
{
get { return id; }
set { id = value; }
}
[Property]
public string Title
{
get { return title; }
set { title = value; }
}
[Property(ColumnType="StringClob")]
public string Contents
{
get { return contents; }
set { contents = value; }
}
[BelongsTo("blogid")]
public Blog OwnerBlog
{
get { return blog; }
set { blog = value; }
}
[HasAndBelongsToMany(typeof(Category),
Table="PostCategory", ColumnKey="postid", ColumnRef="categoryid")]
public IList Categories
{
get { return categories; }
set { categories = value; }
}
}
[HasAndBelongsToMany(typeof(Category),
Table="PostCategory", ColumnKey="postid", ColumnRef="categoryid")]
public IList Categories
[ActiveRecord("categories")]
public class Category : ActiveRecordBase
{
private int id;
private string title;
private IList posts = new ArrayList();
[PrimaryKey]
private int Id
{
get { return id; }
set { id = value; }
}
[Property]
public string Title
{
get { return title; }
set { title = value; }
}
[HasAndBelongsToMany(typeof(Post),
Table="PostCategory", ColumnKey="categoryid", ColumnRef="postid", Inverse=true)]
public IList Posts
{
get { return posts; }
set { posts = value; }
}
}
其中
{
get { return categories; }
set { categories = value; }
}
表达Category表与PostCategory表之间的关系
而Category类代码为:
using Castle.ActiveRecord;
public class Category : ActiveRecordBase
{
private int id;
private string title;
private IList posts = new ArrayList();
[PrimaryKey]
private int Id
{
get { return id; }
set { id = value; }
}
[Property]
public string Title
{
get { return title; }
set { title = value; }
}
[HasAndBelongsToMany(typeof(Post),
Table="PostCategory", ColumnKey="categoryid", ColumnRef="postid", Inverse=true)]
public IList Posts
{
get { return posts; }
set { posts = value; }
}
}
[HasAndBelongsToMany(typeof(Post),
Table="PostCategory", ColumnKey="categoryid", ColumnRef="postid", Inverse=true)]
public IList Posts
{
get { return posts; }
set { posts = value; }
}
如果在多对多的关系表中还需要存储其他的数据,如上例中的PostCategory表改为:
CREATE TABLE PostCategory
(
[id] [int] IDENTITY (1, 1) NOT NULL,
[postid] [int] NOT NULL,
[categoryid] [int] NOT NULL,
[arbitraryvalue] [int] NULL
) ON [PRIMARY]
其中id字段作为其主键,arbitraryvalue字段则为对应的值,那么PostCategory类代码为:
(
[id] [int] IDENTITY (1, 1) NOT NULL,
[postid] [int] NOT NULL,
[categoryid] [int] NOT NULL,
[arbitraryvalue] [int] NULL
) ON [PRIMARY]
using Castle.ActiveRecord;
using NHibernate.Expression;
[ActiveRecord]
public class PostCategory : ActiveRecordBase
{
private int id;
private Post post;
private Category category;
private int arbitraryvalue;
[PrimaryKey]
private int Id
{
get { return id; }
set { id = value; }
}
[BelongsTo("postid")]
public Post Post
{
get { return post; }
set { post = value; }
}
[BelongsTo("categoryid")]
public Category Category
{
get { return category; }
set { category = value; }
}
[Property]
public int ArbitraryValue
{
get { return arbitraryvalue; }
set { arbitraryvalue = value; }
}
public static PostCategory[] FindByPost(Post post)
{
return FindAll(typeof(PostCategory), Expression.Eq("Post", post));
}
public static PostCategory[] FindByCategory(Category category)
{
return FindAll(typeof(PostCategory), Expression.Eq("Category", category));
}
}
但是,如果使用组合键作为主键,则
需要自定义一个类来作为主键属性的类型,对于组合键类,除了需要加上CompositeKey特性之外,它还需要是可序列化的,并且要求实现Equals和GetHashCode方法,代码为:
using NHibernate.Expression;
[ActiveRecord]
public class PostCategory : ActiveRecordBase
{
private int id;
private Post post;
private Category category;
private int arbitraryvalue;
[PrimaryKey]
private int Id
{
get { return id; }
set { id = value; }
}
[BelongsTo("postid")]
public Post Post
{
get { return post; }
set { post = value; }
}
[BelongsTo("categoryid")]
public Category Category
{
get { return category; }
set { category = value; }
}
[Property]
public int ArbitraryValue
{
get { return arbitraryvalue; }
set { arbitraryvalue = value; }
}
public static PostCategory[] FindByPost(Post post)
{
return FindAll(typeof(PostCategory), Expression.Eq("Post", post));
}
public static PostCategory[] FindByCategory(Category category)
{
return FindAll(typeof(PostCategory), Expression.Eq("Category", category));
}
}
using Castle.ActiveRecord;
using NHibernate.Expression;
[Serializable]
public class PostCategoryKey
{
private int postid;
private int categoryid;
[KeyProperty]
public int PostId
{
get { return postid; }
set { postid = value; }
}
[KeyProperty]
public int CategoryId
{
get { return categoryid; }
set { categoryid = value; }
}
public override int GetHashCode()
{
return postid ^ categoryid;
}
public override bool Equals(object obj)
{
if (this == obj)
{
return true;
}
PostCategoryKey key = obj as PostCategoryKey;
if (key == null)
{
return false;
}
if (postid != key.postid || categoryid != key.categoryid)
{
return false;
}
return true;
}
}
[ActiveRecord]
public class PostCategory : ActiveRecordBase
{
private PostCategoryKey id;
private int arbitraryvalue;
[CompositeKey]
public PostCategoryKey Id
{
get { return id; }
set { id = value; }
}
[Property]
public int ArbitraryValue
{
get { return arbitraryvalue; }
set { arbitraryvalue = value; }
}
public static PostCategory[] FindByPost(Post post)
{
return FindAll(typeof(PostCategory),
Expression.Eq("PostCategory_postid", post.Id));
}
public static PostCategory[] FindByCategory(Category category)
{
return FindAll(typeof(PostCategory),
Expression.Eq("PostCategory_categoryid", category.Id));
}
}
using NHibernate.Expression;
[Serializable]
public class PostCategoryKey
{
private int postid;
private int categoryid;
[KeyProperty]
public int PostId
{
get { return postid; }
set { postid = value; }
}
[KeyProperty]
public int CategoryId
{
get { return categoryid; }
set { categoryid = value; }
}
public override int GetHashCode()
{
return postid ^ categoryid;
}
public override bool Equals(object obj)
{
if (this == obj)
{
return true;
}
PostCategoryKey key = obj as PostCategoryKey;
if (key == null)
{
return false;
}
if (postid != key.postid || categoryid != key.categoryid)
{
return false;
}
return true;
}
}
[ActiveRecord]
public class PostCategory : ActiveRecordBase
{
private PostCategoryKey id;
private int arbitraryvalue;
[CompositeKey]
public PostCategoryKey Id
{
get { return id; }
set { id = value; }
}
[Property]
public int ArbitraryValue
{
get { return arbitraryvalue; }
set { arbitraryvalue = value; }
}
public static PostCategory[] FindByPost(Post post)
{
return FindAll(typeof(PostCategory),
Expression.Eq("PostCategory_postid", post.Id));
}
public static PostCategory[] FindByCategory(Category category)
{
return FindAll(typeof(PostCategory),
Expression.Eq("PostCategory_categoryid", category.Id));
}
}