Castle ActiveRecord 笔记
1 表列
如果你的列名是数据库的保留字,在Property中用"`"声明列名
[Property("`User`")]
public String User
{
get { return _user; }
set { _user = value; }
}
不要使用Status做列名,它是NHibernate的保留字,否则ActiveRecord会抛异常:Ambiguous column name 'Status'
可以使用枚举作为列的类型,在数据库中将创建整数类型的列
2 对象保存到数据库的时机
只有在会话Flush()或事务Commit()的时候,对象才存入数据库
自动保存
* 当session.Find()被调用
* 当Filter()被调用
* 自动保存需要session.FlushMode为Auto(缺省值)
3 对象关系
* 不支持在非主键上建立关系
3.1 BelongsTo
* 表现多对一的关系
* ActiveRecord将为该关系建立数据库表的外键
* 如“用户”相对于“部门", 在“用户”实体类上申明
3.2 HasMany
* 表现一对多的关系
* ActiveRecord将为该关系建立数据库表的外键
* 如“部门”相对于“用户", 在“部门”实体类上申明
[HasMany(typeof(SystemUser))]
public IList<SystemUser> Users
{
get { return _users; }
set { _users = value; }
}
3.3 HasAndBelongsToMany
* 表现多对多的关系
* ActiveRecord将为创建一个关联表
* 如允许一个用户有多个角色的情况下的“用户”和“角色”
3.4 OneToOne
* 表现一对一的关系
* 两个实体(数据库表)拥有相同的数据库表主键,从表实体需将主键类型申明为PrimaryKeyType.Foreign
* 如“用户”和“用户地址”
3.5 Any 和 HasManyToAny
* 用于表示不确定一对多关系
* 如:“设备视频端口”可能保存多种设备(DVR/Matrix/DVS)的端口信息
[ActiveRecord()]
public class DeviceDvr : ActiveRecordBase, IVideoDeivce
{ }
[ActiveRecord()]
public class DeviceDvs : ActiveRecordBase, IVideoDeivce
{ }
[Any(typeof(Guid), MetaType=typeof(string),TypeColumn="DeviceType",IdColumn="DeviceGuid",Cascade=CascadeEnum.SaveUpdate)]
public IVideoDeivce VideoDeivce
{
get { }
set { }
}
4 实体类继承
4.1 单表继承
* 所有父子实体类都保存在一个数据库表中
* “字典”、“设备类型字典”和“设备故障字典”
/* 使用Type列来标示该行数据归属的字典类型 */
[ActiveRecord(DiscriminatorColumn = "Type", DiscriminatorType = "String", DiscriminatorValue = "none")]
public class Dictionary : ActiveRecordBase<Dictionary>
{ }
[ActiveRecord(DiscriminatorValue = "device_type")]
public class DictionaryDeviceType : Dictionary
[ActiveRecord(DiscriminatorValue = "device_failure")]
public class DictionaryDeviceFailure : Dictionary
4.2 类表继承
* 所有父子实体类各拥有一张数据库表,由基类生成主键
* 如: “汽车”、“跑车”和“房车”
5 嵌套的数据 Nested data * 支持用一个非数据库表的数据对象表现数据库表的一个或多个列的集合
* 如:“用户”、“单位”和“地址”,用户和单位表中都有地址信息,地址类只是多个列的集合
* 表现数据库中的一个列是,也可用于定义用户自定义数据,以实现数据库的用户定义数据类型
。 如此可统一各个实体类中相同含义的列的格式定义(Sql数据类型、长度、格式验证等等)
。 如:Emai地址、电话号码
6 延迟加载Lazy load * 延迟加载确保数据只在需要时才从数据库中加载,如“用户”对象中的“部门”在加载“用户”对象时不会被加载
* 如此启用实体的延迟加载: [ActiveRecord(Lazy=true)]
* 除了BelongTo,其他所有关系缺省的都未启用延迟加载
7 数据验证
ActiveRecord提供数据验证器对列数据进行规则验证
验证器在数据库操作(insert,update)之前对数据格式进行验证
实体类需从ActiveRecordValidationBase继承
数据验证器包括:
ValidateIsUnique 检查列值在表中唯一
ValidateRegExp 使用正则表达式验证列数据格式
ValidateEmail 验证列数据为EMail地址格式
ValidateNonEmpty 验证列数据非空
ValidateConfirmation 验证两个属性相同,如密码和密码确认
可继承AbstractValidationAttribut来实现自定义验证器
数据分页
Query
SimpleQuery<SystemUser> userQuery = new SimpleQuery<SystemUser>("from SystemUser where State = :State Order By Name");
userQuery.SetParameter("State", SystemUser.UserState.Valid);
userQuery.SetQueryRange(pageIndex * pageSize, pageSize);
SystemUser[] users = userQuery.Execute();
SliceFindAll
SystemUser[] users = SystemUser.SlicedFindAll(30, 10, null,new ICriterion[] { Expression.Eq("State", SystemUser.UserState.Valid) });
NHibernate用户自定义数据类型
用于在单列中存储更复杂的数据信息(如列表),并以对象的形式来表现
应用场景:不想单独使用一个表来存储这些复杂的数据信息的时候
如:设备报警的端口列表可能为多个,可以将他们存在一个数据库列中,格式如"2,3,5"
表现该列的对象需实现NHibernate的IUserType接口,如public class DeiveAlarmPorts:List<int>,IUserType
如此在DeviceAlarm类中声明属性
[Property("AlarmPorts", "ActiveRecordEntities.Alarm,ActiveRecordEntities")]
public DeiveAlarmPorts AlarmPorts { get {...} set {...}}
引用和链接
ActiveRecord Official Document 自定义数据类型