Castle ActiveRecord学习实践(4):实现One-Many关系的映射

摘要:前面几篇文章简单的介绍了ActiveRecord中的基本映射以及构建配置信息,本文我们用ActiveRecord里面的BlogPost例子来实现One-Many/Many-One关联。

主要内容

1.准备数据表结构

2.编写实体类并介绍HasManyBlongsTo特性

3.构建配置信息

4.编写测试代码

 

一.准备数据表结构

在这个例子中,我们引入了两个对象BlogPost,它们之间的关系是一对多,即一个Blog有多篇Post。需要用到的数据表结构如下

CREATE TABLE Blogs (

    blog_id     
int IDENTITY(11PRIMARY KEY,

    blog_name   
varchar(50),

    blog_author 
varchar(50)

)

 

CREATE TABLE Posts (

    post_id        
int IDENTITY(11PRIMARY KEY,

    post_title     
varchar(50),

    post_contents  
text,

    post_categories 
varchar(50),

    post_blogid    
int FOREIGN KEY REFERENCES Blogs (blog_id),

    post_created   
datetime,

    post_published 
bit

)


二.编写实体类

首先我们来看Blog实体类的编写,需要用到HasMany特性,这时我们会在Blog实体类中定义一个Posts属性,用它来表示该Blog所发表的所有Posts,代码如下

 

[ActiveRecord("Blogs")]

public class Blog : ActiveRecordBase

{

    
//……

    
private IList _posts;

 

    [HasMany(
typeof(Post), Table="posts", ColumnKey="post_blogid")]

    
public IList Posts

    
{

        
get return _posts; }

        
set { _posts = value; }

    }


}


HasManyAttribute说明

属性

说明

示例

Cascade

指明哪些操作会从父对象级联到关联的对象,相关的操作见后面,如果不指定,则为None

Cascade=ManyRelationCascadeEnum.All

Inverse

指定是否级联操作

Inverse =true|false

Schema

指定Schema的名字

Schema="ARDemo"

Table

指定持久化类所关联的数据库表名,如果表名与类名相同,可以省略

Table="posts"

ColumnKey

指定关联类的一个属性,这个属性将会和本外键相对应。

ColumnKey="post_blogid"

Where

指定一个附加SQLWhere子句

Where="IsPost = 0"

Lazy

指定是否延迟加载关联对象

Lazy=true|false


Cascade
的类型值有如下几种

类型

说明

None

不进行级联操作

SaveUpdate

进行级联Save/Update操作

Delete

进行级联Delete操作

All

进行级联Save/Update/Delete操作

AllDeleteOrphan

进行级联Save/Update/Delete操作,并删除无相关父对象的子对象

 

Post实体类中,我们需要定义一个Blog类型的属性,并且用到BlongsTo特性,即一个Post属于某一个Blog,代码如下:

[ActiveRecord("Posts")]

public class Post : ActiveRecordBase

{

    
//……

    
private Blog _blog;

 

    [BelongsTo(
"blogid")]

    
public Blog Blog

    
{

        
get return _blog; }

        
set { _blog = value; }

    }


}


BelongsToAttribute说明

属性

说明

示例

Cascade

指定级联操作

Cascade=CascadeEnum.SaveUpdate

Column

列名,外键字段名

BelongsTo("blogid")

Column="blogid"

Insert

是否允许增加

Insert=true|false

NotNull

是否允许为空

NotNull =true|false

OuterJoin

是否允许外连接抓取

OuterJoin=OuterJoinEnum.True

Unique

是否唯一

Unique =true|false

Update

是否允许更新

Update =true|false

 

Cascade类型如下

选项

说明

None

默认值,不进行级联操作

All

进行级联Save/Update/Delete操作

SaveUpdate

进行级联Save/Update操作

Delete

进行级联Delete操作

 

OuterJoin选项有三个:AutoTrueFalse

最后完整的Blog实体类如下

/// <summary>

/// Blog 的摘要说明。

/// </summary>


[ActiveRecord(
"Blogs")]

public class Blog : ActiveRecordBase

{

    
private int _id;

 

    
private String _name;

 

    
private String _author;

 

    
private IList _posts;

 

    [PrimaryKey(PrimaryKeyType.Native, 
"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; }

    }


    

    [HasMany(
typeof(Post), Table="posts", ColumnKey="post_blogid")]

    
public IList Posts

    
{

        
get return _posts; }

        
set { _posts = 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 );

    }


}

 

完整的Post类如下


/// <summary>

/// Post 的摘要说明。

/// </summary>


[ActiveRecord(
"Posts")]

public class Post : ActiveRecordBase

{

    
private int _id;

 

    
private String _title;

 

    
private String _contents;

 

    
private String _category;

 

    
private DateTime _created;

 

    
private bool _published;

 

    
private Blog _blog;

 

    
public Post()

    
{

        _created 
= DateTime.Now;

    }


 

    
public Post(Blog blog, String title, String contents, String category) : this()

    
{

        _blog 
= blog;

        _title 
= title;

        _contents 
= contents;