本章只学习下ActiveRecord的一些常见的映射配置,比如主键配置、属性配置、字段配置、一对多、多对多等配置,像继承、复合主键自己可参考官网文档,地址:http://docs.castleproject.org/Active%20Record.MainPage.ashx。
一些映射的属性描述可以查看博客http://terrylee.cnblogs.com/archive/2006/04/06/367978.html,这个系列的博客对于ActiveRecord的学习是基于比较老版本的,目前一些方法的调用等不适用于最新版本,但是对于ActiveRecord的属性配置还是可以参考的。
主键配置
[PrimaryKey(PrimaryKeyType.Identity)]
public int Id { get; set; }
PrimaryKey是主键的配置属性,PrimaryKeyType是主键的生成方式,这里是数据库自增型的
(当然官网是不建议使用这种主键类型的)
以下是主键的生成方式(摘自rrylee.cnblogs.com/archive/2006/04/06/367978.html):
名称 | 说明 |
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 | 使用另外一个相关联的对象的标识符。 |
属性配置
[Property(ColumnType = "StringClob")]
public string Contents { get; set; }
基本的属性字段配置,可以设置对应数据库字段的名称为StringClob
字段配置
ActiveRecord还额外支持私有字段的配置(不过一般不用)
[Field]
private string name;
一对多
首先新建数据表(一个Blogs(博客)对于多篇Posts(文章))
CREATE TABLE Blogs
(
[id] [int] IDENTITY (1, 1) NOT NULL,
[name] [varchar] (50) NULL
) ON [PRIMARY]
CREATE TABLE Posts
(
[id] [int] IDENTITY (1, 1) NOT NULL,
[title] [varchar] (50) NULL,
[contents] [text] NULL,
[blogid] [int] NULL
) ON [PRIMARY]
对应的配置如下:
[ActiveRecord("blogs")]
public class Blog : ActiveRecordBase<Blog>
{
[PrimaryKey(PrimaryKeyType.Identity)]
private int Id { get; set; }
[Property]
public string Name { get; set; }
[HasMany(typeof(Post), Table = "Posts", ColumnKey = "blogid",Cascade=ManyRelationCascadeEnum.All,Inverse=true)]
public IList Posts { get; set; }
}
[ActiveRecord("posts")]
public class Post : ActiveRecordBase<Blog>
{
[PrimaryKey(PrimaryKeyType.Identity)]
public int Id { get; set; }
[Property]
public string Title { get; set; }
[Property(ColumnType = "StringClob")]
public string Contents { get; set; }
[BelongsTo("blogid")]
public Blog OwnerBlog { get; set; }
}
其中Cascade=ManyRelationCascadeEnum.All是设置为级联操作,即创建与删除实体的时候会对关联的实体产生对应的影响,比如删除Blog的一条记录,则会自动将Posts对应的记录的blogid字段置空。
客户端调用代码如下:
Blog blog = new Blog();
blog.Name = "Eye_cng的博客";
blog.Create();
Post post = new Post();
post.Title = "第一篇文章";
post.Contents = "文章内容";
post.OwnerBlog = blog;
post.Create();
多对多
多对多关系,一般处理方式是在数据库中建立中间表,多对多的表不进行关联,都与中间表进行一对多的关联。若中间表只存储两个多的表的主键的话可以只配置两张多的表的属性,中间表不需要实体承载。但如果中间表存在额外字段的话,就需要把它当做两个一对多进行配置了。下面来讲讲中间表只有两个字段的配置。
Post(文章)和Category(分类)是多对多,数据库表如下(Post 上篇已经建立数据库表):
CREATE TABLE Categories
(
[id] [int] IDENTITY (1, 1) NOT NULL,
[title] [varchar] (50) NULL,
) ON [PRIMARY]
CREATE TABLE PostCategory
(
[id] [int] IDENTITY (1, 1) NOT NULL,
[postid] [int] NOT NULL,
[categoryid] [int] NOT NULL,
[arbitraryvalue] [int] NULL
) ON [PRIMARY]
Post参照上面的配置,只需再加个字段:
[HasAndBelongsToMany(typeof(Category),Table = "PostCategory", ColumnKey = "postid", ColumnRef = "categoryid")]
public IList Categories { get; set; }
[ActiveRecord("categories")]
public class Category : ActiveRecordBase
{
[PrimaryKey]
private int Id { get; set; }
[Property]
public string Title { get; set; }
[HasAndBelongsToMany(typeof(Post),Table = "PostCategory", ColumnKey = "categoryid", ColumnRef = "postid", Inverse = true)]
public IList Posts { get; set; }
}
中间表无需配置。
客户端调用代码如下:
Blog blog = new Blog();
blog.Name = "Eye_cng的博客";
blog.Create();
Category category = new Category();
category.Title = "分类一";
category.Create();
Post post = new Post();
post.Title = "多对多";
post.Contents = "内容";
post.OwnerBlog = blog;
post.Categories = new List<Category>();
post.Categories.Add(category);
post.Create();
组合配置
组合配置就是一个类字段过多(面向对象的说法就是多个属性可以用对象来表示的,比如地址一些字段可以用一个地址对象表示)
配置如下:
[ActiveRecord]
public class Customer : ActiveRecordBase
{
private int id;
private Address address;
[PrimaryKey]
private int Id
{
get { return id; }
set { id = value; }
}
[Nested]
public Address Address
{
get { return street; }
set { street = value; }
}
}
public class Address
{
private string street;
private string city;
private string state;
private string zipcode;
[Property]
public string Street
{
get { return street; }
set { street = 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; }
}
}
用Nested来进行对象的组合配置。
延迟加载
如果一个字段查询对有些方法是有用到的,对于另一些方法是无需使用的,这是我们可以设置这个字段属性配置为延迟加载。
[Property(Lazy=true)]
public string Title { get; set; }
配置了此属性之后,方法在查询时是不会将此字段取出,而只会在使用的时候重新查找数据库的。