Castle ActiveRecord(三) 关联映射

本文介绍了如何使用ActiveRecord框架中的HasMany和BelongsTo特性来建立Blog与Post类之间的关联,并通过示例代码展示了如何正确地进行对象持久化。

ActiveRecord 提供一个DomainModel 工具,它使我们创建对象模型的相互关系非常容易。在上面的例子中我们已经创建了一个Blog类,它完全可以提供一个Post类及它们之间的关联。平白点讲,他们的关联是:

  • 一个Post属于一个Blog

  • 一个Blog有多个Post

使用HasMany特性 和BelongsTo特性

必须使用HasMany和BelongTo特性表达对象之间的关联。如下:

None.gif[ActiveRecord("Blogs")]
None.gif
public class Blog : ActiveRecordBase
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifdot.gif
InBlock.gif    
private IList _posts;
InBlock.gifdot.gif
InBlock.gif    [HasMany(
typeof(Post), Table="posts", ColumnKey="post_blogid")]
InBlock.gif    
public IList Posts
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _posts; }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ _posts = value; }
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif[ActiveRecord(
"Posts")]
None.gif
public class Post : ActiveRecordBase
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifdot.gif
InBlock.gif    
private Blog _blog;
InBlock.gifdot.gif
InBlock.gif    [BelongsTo(
"post_blogid")]
InBlock.gif    
public Blog Blog
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _blog; }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ _blog = value; }
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

在这个例子中,由于Post有一个BelongTo联合,ActiveRecord能够收集到这个信息并创建正确的HasMany,因此不必指定所有信息,象下面这样就可以了,注意对比“[HasMany(typeof(Post))]”:

None.gif[ActiveRecord("Blogs")]
None.gif
public class Blog : ActiveRecordBase
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifdot.gif
InBlock.gif    
private IList _posts;
InBlock.gifdot.gif
InBlock.gif    [HasMany(
typeof(Post))]
InBlock.gif    
public IList Posts
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _posts; }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ _posts = value; }
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

不要感到疑惑,让我们看看Post类,注意[BelongsTo("post_blogid")]

None.gifusing System;
None.gif
using System.Collections.Generic;
None.gif
using System.Text;
None.gif
None.gif
namespace ActiveRecord
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif   
using Castle.ActiveRecord;
InBlock.gif    [ActiveRecord(
"Posts")]
InBlock.gif    
public class Post : ActiveRecordBase
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
InBlock.gif        
private int _postId;
InBlock.gif        
private string _postTitle;
InBlock.gif        
private string _postContents;
InBlock.gif        
private string _postCategory;
InBlock.gif        
private System.DateTime _postCreated;
InBlock.gif        
private bool _postPublished;
InBlock.gif        
private Blog _blog;
InBlock.gif
InBlock.gif        [PrimaryKey(PrimaryKeyType.Native, 
"post_id")]
InBlock.gif        
public int PostId
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return this._postId;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this._postId = value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        [Property(Column 
= "post_title")]
InBlock.gif        
public string PostTitle
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return this._postTitle;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this._postTitle = value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        [Property(Column 
= "post_contents")]
InBlock.gif        
public string PostContents
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return this._postContents;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this._postContents = value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        [Property(Column 
= "post_category")]
InBlock.gif        
public string PostCategory
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return this._postCategory;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this._postCategory = value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        [Property(Column 
= "post_created")]
InBlock.gif        
public System.DateTime PostCreated
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return this._postCreated;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this._postCreated = value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        [Property(Column 
= "post_published")]
InBlock.gif        
public bool PostPublished
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return this._postPublished;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this._postPublished = value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        [BelongsTo(
"post_blogid")]
InBlock.gif        
public Blog Blog
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return this._blog;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this._blog = value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public static void DeleteAll()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            ActiveRecordBase.DeleteAll(
typeof(Post));
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public static Post[] FindAll()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return ((Post[])(ActiveRecordBase.FindAll(typeof(Post))));
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public static Post Find(int PostId)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return ((Post)(ActiveRecordBase.FindByPrimaryKey(typeof(Post), PostId)));
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

好,我们来看看怎么使用关联映射吧。先看下面的代码:

None.gifBlog blog = Blog.Find(1);
None.gifnewPost.PostTitle 
= "MyPostTitle";
None.gifnewPost.PostPublished 
= true;
None.gifnewPost.PostContents 
= "This is a great post!";
None.gifnewPost.PostCategory 
= "Blogging";
None.gifnewPost.PostCreated 
= DateTime.Now;
None.gifblog.Posts.Add(newPost );
None.gifblog.Save(); 

这段代码是无法正常运行的,因为Post类是一个瞬态类,在使用时我们必须先持久化它,象下面这样就可以运行了:

None.gifBlog blog = Blog.Find(1);
None.gifPost newPost 
= new Post();
None.gifnewPost.PostTitle 
= "MyPostTitle";
None.gifnewPost.PostPublished 
= true;
None.gifnewPost.PostContents 
= "This is a great post!";
None.gifnewPost.PostCategory 
= "Blogging";
None.gifnewPost.PostCreated 
= DateTime.Now;
None.gifnewPost.Blog 
= blog;
None.gifnewPost.Save();
None.gifblog.Posts.Add(newPost);
None.gifblog.Save(); 
None.gif

不过你的Blogs表中要有记录才行,否则会发生异常,告诉你找不到。又有人不禁想出了下面的代码:

None.gifBlog blog = New Blog();
None.gifblog.BlogName
="blogname";
None.gifblog.BlogAuthor
="This is my first post");
None.gifPost newPost 
= new Post();
None.gifnewPost.PostTitle 
= "MyPostTitle";
None.gifnewPost.PostPublished 
= true;
None.gifnewPost.PostContents 
= "This is a great post!";
None.gifnewPost.PostCategory 
= "Blogging";
None.gifnewPost.PostCreated 
= DateTime.Now;
None.gifnewPost.Save();
None.gifblog.Posts.Add(newPost);
None.gifblog.Save(); 

这样还是不行地,在向数据库里面保存时,Post实际需要的是BlogId,而此时Blog还没有Id

上面的代码都使用了Blog端的关联,也可以象下面这样使用:

None.gifBlog blog = Blog.Find(1);
None.gifPost newPost 
= new Post();
None.gifnewPost.PostTitle 
= "MyPostTitle";
None.gifnewPost.PostPublished 
= true;
None.gifnewPost.PostContents 
= "This is a great post!";
None.gifnewPost.PostCategory 
= "Blogging";
None.gifnewPost.PostCreated 
= DateTime.Now;
None.gifnewPost.Blog 
= blog;
None.gifnewPost.Blog 
= blog; // Linking them
None.gif
newPost.Save();
None.gif

处理blog的时候,Posts不会自动地得到通知。如果想应用最新的改变,也好就是说要想使用新实例化的post,必须“刷新”它。我们可以通过设置级联变化来使用它:

None.gif[HasMany(typeof(Post), Table="Posts", ColumnKey="post_blogid", Cascade=ManyRelationCascadeEnum.SaveUpdate)]
None.gif
public IList Posts
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif    
get dot.gifreturn _posts; }
ExpandedSubBlockStart.gifContractedSubBlock.gif    
set dot.gif{ _posts = value; }
ExpandedBlockEnd.gif}

None.gif

这样的开头那段代码就能运行了:

None.gifBlog blog = Blog.Find(1);
None.gifnewPost.PostTitle 
= "MyPostTitle";
None.gifnewPost.PostPublished 
= true;
None.gifnewPost.PostContents 
= "This is a great post!";
None.gifnewPost.PostCategory 
= "Blogging";
None.gifnewPost.PostCreated 
= DateTime.Now;
None.gifblog.Posts.Add(newPost );
None.gifblog.Save(); 
None.gif

怎么样,一定有点晕了吧,不要紧,下一节我们将讲解一下HasManyAttributeBelongsToAttribute






转载于:https://www.cnblogs.com/ttinfo/archive/2006/07/27/461180.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值