本文将介绍Castle ActiveRecord 中的基本映射。
1: [ActiveRecord("Posts")]
2: public class Post:ActiveRecordBase<Post>
3: {
4: [PrimaryKey("PostId")]
5: public int Id { get; set; }
6:
7: [Property]
8: public string Subject { get; set; }
9:
10: [Property]
11: public string Text { get; set; }
12:
13: [Property]
14: public DateTime DateAdded { get; set; }
15:
16: [HasMany]
17: public IList<Comment> Comments { get; set; }
18: 个o
19:
20: }
上面的的代码中已经包含了部分特性(ActiveRecord、Property、PrimaryKey、HasMany),这些特性类在Castle.ActiveRecord 命名空间中。主要的有
ActiveRecordAttribute
PropertyAttribute
PrimaryKeyAttribute
CompositeKeyAttribute
FieldAttribute
ActiveRecordAttribute
每一个实体类都必须继承于ActiveRecordBase,并在实体类上设置特性ActiveRecordAttribute
ActiveRecordAttribute的成员
属性 |
类型 |
说明 |
示例 |
BatchSize | int | 为获取此类的实例标识符指定"批处理大小" | |
DiscriminatorColumn | string | 识别器的字段名 | DiscriminatorColumn="Post" |
DiscriminatorLength | string | 识别器的长度 | |
DiscriminatorType | string | 识别器的字段类型(int、string) | DiscriminatorType=”string” |
DiscriminatorValue | string | 识别器字段的值 | |
DynamicInsert | bool | From NHibernate documentation: Specifies that INSERT SQL should be generated at runtime and contain only the columns whose values are not null. 如果没有对成员变量赋值,直接调用SAVE方法的话,SQL字段中允许为NULL的字段就可以由sql赋予其默认值。因为如果不是可以为Null的话,nhibernate直接会给你个异常,告诉你有notnull字段没有初始化 | |
DynamicUpdate | bool | From NHibernate documentation: Specifies that UPDATE SQL should be generated at runtime and contain only those columns whose values have changed. | |
Lazy | bool | Enable lazy loading for the type 指定是否延迟加载 |
|
LazySpecified | bool | Gets a value indicating whether explicit lazy behavior was specified. If explicit lazy behavior was not specified, it goes to the configuration to decide if the type should be lazy or not | |
Locking |
Castle.ActiveRecord.OptimisticLocking |
From NHibernate documentation: Determines the optimistic locking strategy. 确定乐观的锁定策略 | |
Mutable | bool | From NHibernate documentation: Specifies that instances of the class are (not) mutable 指定类的实例 (不) 是可变 |
|
Persister | System.Type | From NHibernate documentation: Specifies a custom IEntityPersister. | |
Polymorphism |
Castle.ActiveRecord.Polymorphism |
From NHibernate documentation: Determines whether implicit or explicit query polymorphism is used. | |
Proxy | System.Type | From NHibernate documentation: Determines whether implicit or explicit query polymorphism is used. 指定一个接口,在延迟装载时作为代理使用 |
|
Schema | string |
Gets or sets the schema name associated with the type |
|
SchemaAction | string | ||
SelectBeforeUpdate | bool | From NHibernate documentation: Specifies that NHibernate should never perform an SQL UPDATE unless it is certain that an object is actually modified. In certain cases (actually, only when a transient object has been associated with a new session using update()), this means that NHibernate will perform an extra SQL SELECT to determine if an UPDATE is actually required. 指定 NHibernate 应该永远不会执行 SQL 更新,除非它是某些对象实际修改。在某些情况下 (其实,只有当瞬态对象已经与使用 update()) 新会话相关联,这意味着 NHibernate 将执行额外 SQL SELECT 来确定是否确实需要更新。 |
|
Table | string |
Gets or sets the table name associated with the type |
[ActiveRecord("Posts")] [ActiveRecord(Table=" Posts ")] |
Tuplizer | System.Type | ||
UseAutoImport | bool | From NHibernate documentation: The auto-import attribute lets us use unqualified class names in the query language, by default. The assembly and namespace attributes specify the assembly where persistent classes are located and the namespace they are declared in. 自动导入属性允许我们在查询语言中,默认情况下使用非限定的类名。程序集和命名空间的属性指定持久性类所在的程序集和命名空间中声明它们。 |
|
Where | string |
SQL condition to retrieve objects |
PropertyAttribute
在ActiveRecord中通过PropertyAttribute 来指定实体类属性有数据库表中的字段映射
属性 |
类型 |
说明 |
示例 |
Check | string |
From NHibernate documentation: create an SQL check constraint on either column or table |
|
Column | string |
Gets or sets the column name |
Property("PostId") |
ColumnType | string |
Gets or sets the type of the column. |
|
Default | string | ||
Formula | string |
Gets or sets the formula used to calculate this property |
|
Index | string | From NHibernate documentation: specifies the name of a (multi-column) index 指定 (多列) 的索引的名称 |
|
Insert | bool |
Set to false to ignore this property when inserting entities of this ActiveRecord class. 表明在用于INSERT的SQL语句中是否包含这个字段。默认为true |
|
IsOverride | bool | ||
Lazy | bool | ||
Length | int |
Gets or sets the length of the property (for strings - nvarchar(50) ) |
|
NotNull | bool |
Gets or sets a value indicating whether this property allow null. |
|
SqlType | string |
From NHibernate documentation: overrides the default column type |
|
Unique | bool |
Gets or sets a value indicating whether this PropertyAttribute is unique. |
|
UniqueKey | string | From NHibernate documentation: A unique-key attribute can be used to group columns in a single unit key constraint. | |
Update | bool |
Set to false to ignore this property when updating entities of this ActiveRecord class. 表明在用于UPDATE的SQL语句中是否包含这个字段。默认为true |
PrimaryKeyAttribute
在实体类中,通过PrimaryKeyAttribute来指定表的主键
属性 |
类型 |
说明 |
示例 |
Column | string |
Gets or sets the column name |
PrimaryKey("PostId") |
ColumnType | string |
Gets or sets the type of the column. |
|
CustomGenerator | System.Type |
Gets or sets the custom generator. The generator must implement IIdentifierGenerator |
|
Generator | Castle.ActiveRecord.PrimaryKeyType |
Gets or sets the generator. |
|
IsOverride | bool | ||
Length | int |
Gets or sets the length of values in the column |
|
Params | string |
Comma separated value of parameters to the generator |
|
SequenceName | string |
Gets or sets the name of the sequence. |
PrimaryKey(PrimaryKeyType.Sequence, SequenceName="myseqname") |
UnsavedValue | string |
Gets or sets the unsaved value. |
PrimaryKeyType 主键生成方式的枚举
名称 |
说明 |
Assigned |
The primary key value is always assigned. Note: using this you will lose the ability to call Save(), and will need to call Create() or Update() explicitly. |
Counter |
Returns a Int64 constructed from the system time and a counter value. |
Custom |
A custom generator will be provided. See CustomGenerator |
Foreign |
This is a foreign key to another table |
Guid |
Generate a Guid for the primary key Note: You should prefer using GuidComb over this value. |
GuidComb |
Generate a Guid in sequence, so it will have better insert performance in the DB. |
HiLo |
Use the HiLo algorithm to get the next value |
Identity |
Use Identity column (auto number) Note: This force an immediate call to the DB when Create() is called |
Increment |
Returns a Int64, constructed by counting from the maximum primary key value at startup. |
Native |
Use an identity or sequence if supported by the database, otherwise, use the HiLo algorithm |
SeqHiLo |
Use a sequence and a HiLo algorithm - better performance on Oracle |
Sequence |
Use a sequence |
UuidHex |
Use the hex representation of a unique identifier |
UuidString |
Use the string representation of a unique identifier |
CompositeKeyAttribute
组合键比较麻烦,这里还是准备了个demo
和前面的博客差不多,新建表Tags TagPost
Post 类
1: [ActiveRecord("Posts")]
2: public class Post : ActiveRecordBase<Post>
3: {
4: [PrimaryKey("PostId")]
5: public int Id { get; set; }
6:
7: [Property]
8: public string Subject { get; set; }
9:
10: [Property]
11: public string Text { get; set; }
12:
13: [Property]
14: public DateTime DateAdded { get; set; }
15:
16: [BelongsTo("CategoryId")]
17: public Category Category { get; set; }
18:
19: [HasMany]
20: public IList<Comment> Comments { get; set; }
21:
22: [HasAndBelongsToMany(typeof(Tag), Table = "TagPost", ColumnKey = "PostId", ColumnRef = "TagId")]
23: public IList<Tag> Tag { get; set; }
24:
25: }
主要的部分
[HasAndBelongsToMany(typeof(Tag), Table = "TagPost", ColumnKey = "PostId", ColumnRef = "TagId")]
public IList<Tag> Tag { get; set; }
表达tag表与TagPost的关系
Tag类
1: [ActiveRecord("Tags")]
2: public class Tag : ActiveRecordBase<Tag>
3: {
4: [PrimaryKey("TagId")]
5: public int Id { get; set; }
6:
7: [Property("Tag")]
8: public string TagName { get; set; }
9:
10: [HasAndBelongsToMany(typeof(Post), Table = "TagPost", ColumnKey = "TagId", ColumnRef = "PostId")]
11: public IList<Post> Post { get; set; }
12: }
与上面的Post类相同 10-12 行代码表示的 Post表与TagPost的关系
使用组合键作为主键,需要自定义一个类来作为主键属性的类型。
新建类 TagPostKey
1: [Serializable]
2: public class TagPostKey
3: {
4: [KeyProperty]
5: public int PostId { get; set; }
6: [KeyProperty]
7: public int TagId { get; set; }
8:
9: public override int GetHashCode()
10: {
11: return TagId ^ PostId;
12: }
13:
14: public override string ToString()
15: {
16:
17: return string.Join(":", new string[] { PostId.ToString(), TagId.ToString() });
18: }
19: public override bool Equals(object obj)
20: {
21: if (this==obj)
22: {
23: return true;
24: }
25: TagPostKey key = obj as TagPostKey;
26: if (key==null)
27: {
28: return false;
29: }
30: if (PostId!=key.PostId||TagId!=key.TagId)
31: {
32: return false;
33: }
34: return true;
35: }
36: }
注意 该类必须能够序列化,还需重写Equals和GetHashCode方法
TagPost类
1: [ActiveRecord]
2: public class TagPost:ActiveRecordBase<TagPost>
3: {
4: [CompositeKey]
5: public TagPostKey Id { get; set; }
6:
7: }
FieldAttribute
在ActiveRecord中,允许我们直接对Field进行映射,使用FieldAttribute
1: [ActiveRecord]
2: public class TagPost:ActiveRecordBase<TagPost>
3: {
4: [CompositeKey]
5: public TagPostKey Id { get; set; }
6:
7:
8: [Field("ArbitraryValue")]
9: int _arbitraryValue;
10: }