摘要:本文详细介绍了ActiveRecord中的基本映射,对于关联映射会在后续文章中通过一些具体的实例来说明。
主要内容
简单映射
1.ActiveRecordAttribute
2. PrimaryKeyAttribute
3.CompositeKeyAttribute
4.PropertyAttribute
5.FieldAttribute
一.ActiveRecordAttribute
每一个实体类都必须继承于基类ActiveRecordBase,并在实体类上设置特性ActiveRecordAttribute,示例代码
//指定数据库表名

[ActiveRecord("Blogs")]

public class Blog : ActiveRecordBase



{

//

}

//不指定数据库表名

[ActiveRecord]

public class Blog : ActiveRecordBase



{

//

}
ActiveRecordAttribute说明
|
属性
|
说明
|
示例
|
|
Table
|
指定持久化类所对应的数据库表名,如果表名与类名相同,可以省略
|
[ActiveRecord("Blogs")]
[ActiveRecord(Table="Blogs")]
|
|
Schema
|
指定Schema的名字
|
Schema="ARDemo"
|
|
Proxy
|
指定一个接口,在延迟装载时作为代理使用
|
|
|
DiscriminatorColumn
|
识别器的字段名
|
DiscriminatorColumn="Blog"
|
|
DiscriminatorType
|
识别器的字段类型
|
DiscriminatorType="String"
|
|
DiscriminatorValue
|
识别器字段的值
|
|
|
Where
|
指定一个附加SQL的Where子句
|
Where="IsPost = 0"
|
|
Lazy
|
指定是否延迟加载
|
Lazy=true|false
|
二.PrimaryKeyAttribute
在实体类中,通过PrimaryKeyAttribute来指定表的主键,示例代码
//指定主键字段名

[ActiveRecord()]

public class Blog : ActiveRecordBase



{

private int id;


[PrimaryKey("blog_id")]

public int Id


{


get
{ return id; }


set
{ id = value; }

}

}

//不指定主键字段名

[ActiveRecord()]

public class Blog : ActiveRecordBase



{

private int id;


[PrimaryKey]

public int Id


{


get
{ return id; }


set
{ id = value; }

}

}

PrimaryKeyAttribute说明
|
属性
|
说明
|
示例
|
|
PrimaryKeyType
|
主键生成的方式,如果不指定,则默认的方式为PrimaryKeyType.Native
|
PrimaryKeyType.Native
|
|
Column
|
主键字段名称,如果跟属性名相同,可以不用指定
|
PrimaryKey("blog_id")
|
|
ColumnType
|
主键字段的类型
|
|
|
Generator
|
是一个.NET类的名字,用来为该持久化类的实例生成唯一的标识。
|
|
|
Params
|
用Params来提供Generator所需要的配置参数或初始化参数
|
|
|
Length
|
主键字段的长度
|
Length=10
|
|
SequenceName
|
当指定主键的生成方式为Sequence时,序列的名称
|
PrimaryKey(PrimaryKeyType.Sequence, SequenceName="myseqname")
|
|
UnsavedValue
|
用来标志该实例是刚刚创建的,尚未保存。
|
|
主键的生成方式介绍
|
名称
|
说明
|
|
Identity
|
对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持,生成自增的整型
|
|
Sequence
|
序列,对DB2,MySQL, PostgreSQL, Oracle的内置标识字段提供支持,生成自增的整型。
|
|
HiLo
|
高低位,使用一个高/低位算法来高效的生成Int64, Int32 或者 Int16类型的标识符。
|
|
SeqHiLo
|
使用序列的高低位,使用一个高/低位算法来高效的生成Int64, Int32 或者 Int16类型的标识符,给定一个数据库序列(sequence)的名字。
|
|
UuidHex
|
用一个System.Guid和它的ToString(string format)方法生成字符串类型的标识符。
|
|
UuidString
|
用一个新的System.Guid产生一个byte[] ,把它转换成字符串。
|
|
Guid
|
用一个新的System.Guid 作为标识符。
|
|
GuidComb
|
用Jimmy Nilsso的一个算法产生一个新的System.Guid。
|
|
Native
|
根据底层数据库的能力选择 identity, sequence 或者 hilo中的一个。默认值。
|
|
Assigned
|
让应用程序在自己为对象分配一个标示符。
|
|
Foreign
|
使用另外一个相关联的对象的标识符。
|
三.CompositeKeyAttribute
如果使用组合键,需要我们自定义一个类来作为主键属性的类型。示例代码
[PrimaryKey]

public MyCompositeKey ID



{


get
{ return _key; }


set
{ _key = value; }

}
对于组合键类,除了需要加上CompositeKey特性之外,它还需要是可序列化的,并且要求实现Equals和GetHashCode方法。ActiveRecord官方网站上提供的一个组合键的示例程序如下:
[CompositeKey, Serializable]

public class MyCompositeKey



{

private string _keyA;

private string _keyB;


[KeyProperty]

public virtual string KeyA


{


get
{ return _keyA; }


set
{ _keyA = value; }

}


[KeyProperty]

public virtual string KeyB


{


get
{ return _keyB; }


set
{ _keyB = value; }

}


public override string ToString()


{


return string.Join( ":", new string[]
{ _keyA, _keyB } );

}


public override bool Equals( object obj )


{

if( obj == this ) return true;

if( obj == null || obj.GetType() != this.GetType() ) return false;

MyCompositeKey test = ( MyCompositeKey ) obj;

return ( _keyA == test.KeyA || (_keyA != null && _keyA.Equals( test.KeyA ) ) ) &&

( _keyB == test.KeyB || ( _keyB != null && _keyB.Equals( test.KeyB ) ) );

}


public override int GetHashCode()


{

return _keyA.GetHashCode() ^ _keyB.GetHashCode();

}

}
四.PropertyAttribute
在ActiveRecord中通过PropertyAttribute来指定实体类属性与数据库中的字段映射。
[ActiveRecord()]

public class Blog : ActiveRecordBase



{

//不指定字段名

[Property]

public int Name


{


get
{ return _name; }


set
{ _name = value; }

}

}


[ActiveRecord()]

public class Blog : ActiveRecordBase



{

//指定字段名

[Property("blog_name")]

public int Name


{


get
{ return _name; }


set
{ _name = value; }

}

}
PropertyAttribute说明
|
属性
|
说明
|
示例
|
|
Column
|
对应的数据库字段名
|
Property("blog_name")
|
|
ColumnType
|
对应的字段类型
|
|
|
Formula
|
一个SQL表达式,定义了这个计算(computed) 属性的值。计算属性没有和它对应的数据库字段。
|
|
|
UnsavedValue
|
用来标志该实例是刚刚创建的,尚未保存。
|
|
|
Length
|
字段的长度
|
Length=10
|
|
NotNull
|
是否可以为空
|
NotNull=true|false
|
|
Unique
|
是否允许重复
|
Unique=true|false
|
|
Update
|
表明在用于UPDATE 的SQL语句中是否包含这个字段。默认为true
|
Update=true|false
|
|
Insert
|
表明在用于INSERT的SQL语句中是否包含这个字段。默认为true
|
Insert=true|false
|
五.FieldAttribute
在ActiveRecord中,允许我们直接对Field进行映射,使用FieldAttribute
[ActiveRecord()]

public class Blog : ActiveRecordBase



{

//不指定字段名称

[Field]

string _name;

}


[ActiveRecord()]

public class Blog : ActiveRecordBase



{

//指定字段名称

[Field("blog_name")]

string _name;

}
FieldAttribute说明
|
属性
|
说明
|
示例
|
|
Column
|
对应的数据库字段名
|
Property("blog_name")
|
|
ColumnType
|
对应的字段类型
|
|
|
Formula
|
一个SQL表达式,定义了这个计算(computed) 属性的值。计算属性没有和它对应的数据库字段。
|
|
|
UnsavedValue
|
用来标志该实例是刚刚创建的,尚未保存。
|
|
|
Length
|
字段的长度
|
Length=10
|
|
NotNull
|
是否可以为空
|
NotNull=true|false
|
|
Unique
|
是否允许重复
|
Unique=true|false
|
|
Update
|
表明在用于UPDATE 的SQL语句中是否包含这个字段。默认为true
|
Update=true|false
|
|
Insert
|
表明在用于INSERT的SQL语句中是否包含这个字段。默认为true
|
Insert=true|false
|
六.NestedAttribute
在映射的时候我们也可以用子对象来映射数据库中的字段,示例代码
[ActiveRecord]

public class Company : ActiveRecordBase



{

private PostalAddress _address;


[Nested]

public PostalAddress Address


{


get
{ return _address; }


set
{ _address = value; }

}

}


public class PostalAddress



{

private String _address;

private String _city;

private String _state;

private String _zipcode;


public PostalAddress()


{

}


public PostalAddress(String address, String city,

String state, String zipcode)


{

_address = address;

_city = city;

_state = state;

_zipcode = zipcode;

}


[Property]

public String Address


{


get
{ return _address; }


set
{ _address = value; }

}


[Property]

public String City


{


get
{ return _city; }


set
{ _city = value;}

}


[Property]

public String State


{


get
{ return _state; }


set
{ _state = value; }

}


[Property]

public String ZipCode


{


get
{ return _zipcode; }


set
{ _zipcode = value; }

}

}
NestedAttribute说明
|
属性
|
说明
|
示例
|
|
Update
|
表明在用于UPDATE 的SQL语句中是否包含这个字段。默认为true
|
Update=true|false
|
|
Insert
|
表明在用于INSERT的SQL语句中是否包含这个字段。默认为true
|
Insert=true|false
|
基本的映射就介绍这么多了,剩下的还有版本(VersionAttribute),时间戳(TimestampAttribute)等映射大家可以参考相关的文档。在下篇文章中我会通过一个具体的实例介绍实现One-Many/Many-One映射。
参考资料
Castle的官方网站http://www.castleproject.org
posted @ 2006-04-06 08:28
TerryLee 阅读(12220)
评论(31) 编辑 收藏 网摘 所属分类:
[11] 数据持久[12] 开源世界
发表评论
看起来就是把nh的映射文件属性化了
nested的概念是否就是nh里的one2one的概念?
#2楼[
楼主]2006-04-06 11:35 |
@windwolf
ActiveRecord就是利用特性来代替了NH中的映射文件
nested并不是one2one的概念,它是对应的同一实体类,只不同通过一些子对象来实现映射。
one2one对应的是不同的实体类,通过OneToOneAttribute来实现。
我用了你有User这个类的一个例子,发现在执行user.Create();程序报错信息“could not perform save for user”,不知道什么原因,我是第一次用ActiveRecord。
#4楼[
楼主]2006-06-01 11:04 |
@wujun
1.看User有没有继承与ActiveRecordBase,并且在类上使用特性[ActiveRecord]
2.看有没有初始化
ActiveRecordStarter.Initialize( source, typeof(User) );
@TerryLee
Could not perform Save for BlogCastle.ActiveRecord
有Blog这个类
初始化方法:
void Application_Start(object sender, EventArgs e)
{
IConfigurationSource source = System.Configuration.ConfigurationManager.GetSection("activerecord") as IConfigurationSource;
Type[] paramTypes = new Type[3];
paramTypes[0] = typeof(User1);
paramTypes[1] = typeof(Post);
paramTypes[2] = typeof(Blog);
ActiveRecordStarter.Initialize(source, paramTypes);
// IConfigurationSource source = System.Configuration.ConfigurationManager.GetSection("activerecord") as IConfigurationSource;
// 在应用程序启动时运行的代码
}
#6楼[
楼主]2006-06-05 17:34 |
@初学ActiveRecord
你是不是用的是.NET2.0?
#7楼[
楼主]2006-06-05 17:34 |
@初学ActiveRecord
你是不是用的是.NET2.0?
看一下AR的版本是否正确?
#9楼[
楼主]2006-06-05 18:19 |
@初学ActiveRecord
这个错误我这儿没有出现
现在在不能浮现这个错误,我不太清楚是哪儿出错了:)
@初学ActiveRecord
这个错误我出现过 ConnectionString 错了
#11楼[
楼主]2006-06-21 16:54 |
@一汐
<add assembly="*"/>是哪儿的?
@初学ActiveRecord
看看你的实体类是否与数据库中的字段是否对应好:)
@TerryLee
请问组合键的Property如何写?比如用了两个键进行组合
private int _blogId;
private int _communityId;
[PrimaryKey(PrimaryKeyType.Native, "blog_Id")]
public int BlogId
{
get
{
return this._blogId;
}
set
{
this._blogId = value;
}
}
[PrimaryKey(PrimaryKeyType.Native, "community_Id")]
public int CommunityId
{
get
{
return this._communityId;
}
set
{
this._communityId = value;
}
}
是不是把这两个属性写在自定义的类里面,那么在原来表对应的类里面不在出现,而加入:
[PrimaryKey]
public MyCompositeKey ID
{
get { return _key; }
set { _key = value; }
}
这样写法可以吗?
@TerryLee
另外新建的类需要继承ActiveRecordBase并在开始Initialize吗?
需要对他进行对应表和字段吗
#15楼[
楼主]2006-07-30 13:31 |
@microshot
参见上面的三.CompositeKeyAttribute
不需要继承ActiveRecordBase,但是它应该是可序列化的
@TerryLee
定义了类myBcKey,并在原来的类中定义了这个类,
编译通过,运行在Initialize()时直接出现
To use type 'myBcKey' as a composite id it must have two or more properties marked with the [KeyProperty] attribute.
@TerryLee
OK了,必须要用KeyProperty:)
#18楼[
楼主]2006-07-30 14:01 |
@microshot
-_-
@TerryLee
A,B 两张表 一对多的关系,其中B的外键是B的联合主键的其中一个,这个关系怎么配置呢?
你好, TerryLee ,非常感谢你这一系统的文章,对我帮助很大.我有一个问题想请教一下,
为什么我我设置了DiscriminatorColumn,DiscriminatorType,DiscriminatorValue 但 FindAll还是把所有数据都获取所有了呢
我的设置如下:
DiscriminatorColumn = "TypeId",
DiscriminatorType = "System.Int32",
DiscriminatorValue = "1"
在 .net 1.1 和 2.0 下测试了都一样
#21楼[
楼主]2006-10-25 13:19 |
@阿武
识别器没测试过,你可以使用Where子句来实现啊
@TerryLee
谢谢,我也想到用 Where 来代替,但暂时还没想到两者之间在使用上有什么区别, 或者说 Discriminator 本来就可以当成是 Where 是子一个子集,不知道这样理解有没有问题
刚刚测试了一下,如果添加了Discriminator,那么在添加修改操作TypeId的值就不需要设置了,看来还是跟Where子句配合使用,不知道其它人是不是也是这样处理的
#24楼[
楼主]2006-10-25 22:59 |
@阿武
用Where子句完全就可以了,一直都没用过Discriminator
hi terrylee我的偶像,我今天才开始看的castle,我有个问题想请教
public class Blog : ActiveRecordBase
如上 业务实体都继承自ActiveRecordBase 它是个接口还是个类啊
如果是个类,我想请问
如果我有一个Account类 一个MoneyAccount类
MoneyAccount类很多属性都是继承自Account的
我如何处理这个问题
class Account
{
private string name;
public string Name
{
get{return name;}
set{name=value;}
}
}
class MoneyAccount:Account(我是想这样.C#不是只能继承自1个类吗?那现在怎么解决)
{
}
#28楼[
楼主]2006-12-24 15:55 |
@row
不好意思,上午参加培训去了,刚看到
解决了就好,其实AR是支持这个的
有没有试过在Nest 类中定义 :BeLongTo标记,这个不行,不知道是Bug还是有其它设置 方法?
求助,我用castle查询14万条数据,其中包含该条件的数据有10万条,查询结果用了一分多钟,请问一下,通过castle查询大量数据时,一般使用何种方式?