Active Record快速入门指南

一、概述
  Active Record(中文名:活动记录)是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。关系型数据库往往通过外键来表述实体关系,Active Record 在数据源层面上也将这种关系映射为对象的关联和聚集。
  Active Record 适合非常简单的领域需求,尤其在领域模型和数据库模型十分相似的情况下。如果遇到更加复杂的领域模型结构(例如用到继承、策略的领域模型),往往需要使用分离数据源的领域模型,结合 Data Mapper (数据映射器)使用。
  Active Record 驱动框架一般兼有 ORM 框架的功能,但 Active Record 不是简单的 ORM。著名的例子是全栈(Full Stack) Web 开发框架 Ruby on Rails。
二、准备
   下载:1)Castle.ActiveRecord-3.0.RC.zip    --程序中要引用的dllc包
      2)Castle-bin-net-2.0              --使用执行Castle.ActiveRecord.Generator.exe生成实体类,也可以不用该工具,用手动编写。
 
三、Active Record的使用
  本文以一个博客系统为例。
第一步:创建项目
  1)添加一个解决方案ActiveRecordDemo;
  2)在解决方案里添加一个类库项目ActiveRecordDemo.Model和Mvc应用程序ActiveRecordDemo.UI.MVC2
    在Model项目中引用下载的Castle.ActiveRecord中的所有dll,在MVC项目中引用NHibernate.dll和Castle.ActiveRecord.dll。
第二步:准备数据库表
   在Mvc项目中添加数据库文件Blog.mdf,为了方便,就以文件的方式放在项目中,然后创建两张表:
--Posts表
CREATE TABLE [dbo].[Posts](
    [Id] [int] IDENTITY(1,1) PRIMARY KEY,
    [Subject] [nvarchar](200) NOT NULL,
    [Text] [nvarchar](max) NOT NULL,
    [DateAdded] [datetime] NOT NULL,
)
View Code
--Comments表
CREATE TABLE[Comments](
    [Id] [int] IDENTITY(1,1) PRIMARY KEY,
    [Test] [nvarchar](max) NOT NULL,
    [Author] [nvarchar](50) NOT NULL,
    [DateAdded] [datetime] NOT NULL,
    [PostId] [int] NOT NULL
)
GO

ALTER TABLE [dbo].[Comments] ADD  CONSTRAINT [FK_Comments_Posts2] FOREIGN KEY([PostId])
REFERENCES [dbo].[Posts] ([Id])
GO
View Code

  如果不用数据库文件,也可以在数据库中创建Blog数据库,然后再创建这两张表。

第三步:编写实体类
  在Model项目中添加Post类和Comment类,这连个类分别对应数据库中的Posts和Comments两张表,代码如下。
 
//Comment实体类
[ActiveRecord("Comments")]//Table Name
    public class Comment : ActiveRecordBase<Comment>
    {
        [PrimaryKey]
        public int Id { get; set; }

        [BelongsTo("PostId")]//FK Column name
        public Post Post { get; set; }

        [Property]
        public string Test { get; set; }

        [Property]
        public string Author { get; set; }

        [Property]
        public DateTime DateAdded { get; set; }

    }


//Post实体类
    [ActiveRecord("Posts")]
    public class Post : ActiveRecordBase<Post>//继承
    {
        [PrimaryKey]
        public int Id { get; set; }

        [Property]
        public string Subject { get; set; }

        [Property]
        public string Text { get; set; }

        public string ShortText
        {
            get
            {
                if (Text.Length > 20)
                {
                    return Text.Substring(0, 20) + "...";
                }
                else
                {
                    return Text;
                }
            }
        }

        [HasMany]//Collection
        public IList<Comment> Comments { get; set; }

        [Property]
        public DateTime DateAdded { get; set; }

        public static Post FindLastPost()
        {
            SimpleQuery<Post> q = new SimpleQuery<Post>(@"from Post p order by p.DateAdded desc");
            return (Post)q.Execute()[0];
        }
    }
View Code

第四步:构建配置信息

  我们要告诉ActiveRecord相关的数据库、数据驱动等信息,最简单的就是使用配置文件,如下:
  <!--ActiveRecord配置-->
  <configSections>
    <section name="activeRecord" type="Castle.ActiveRecord.Framework.Config.ActiveRecordSectionHandler,Castle.ActiveRecord"></section>
  </configSections>
  <activeRecord isWeb="true">
    <config>
      <add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
      <add key="dialect" value="NHibernate.Dialect.MsSql2008Dialect"/>
      <add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
      <add key="connection.connection_string" value="Data Source=.;AttachDbFilename=|DataDirectory|\Blog.mdf;user=sa;password=111"/>
      <add key="proxyfactory.factory_class" value="NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle"/>
    </config>
  </activeRecord>
View Code

  用过NHibernate的朋友一定会对这段配置代码很熟悉,没错,因为ActiveRecord在底层封装了NHibernate,所以这里的配置跟使用NHibernate时的配置一样,同样是指定了数据源驱动,连接字符串等信息。如果使用了配置文件在代码中只要这样去初始化就可以了

//网站放在Application_Start()中
IConfigurationSource source = ConfigurationManager.GetSection("activeRecord") as IConfigurationSource; Castle.ActiveRecord.ActiveRecordStarter.Initialize(source,typeof(Post),typeof(Comment));

  另外一种方式是通过代码指定的方式,但是由于这种方式相当于硬编码了,不大推荐使用这种方式。

InPlaceConfigurationSource source = new InPlaceConfigurationSource();

Hashtable properties = new Hashtable();

properties.Add("hibernate.connection.driver_class", "NHibernate.Driver.SqlClientDriver");
properties.Add("hibernate.dialect", "NHibernate.Dialect.MsSql2000Dialect");
properties.Add("hibernate.connection.provider", "NHibernate.Connection.DriverConnectionProvider");
properties.Add("hibernate.connection.connection_string", "UID=sa;Password=111;Initial Catalog=Blog;Data Source=.");

source.Add( typeof(ActiveRecordBase), properties );

ActiveRecordStarter.Initialize( source, typeof(Post) );
View Code

第五步:开始CRUD操作

  添加BolgController,添加视图。

//后台代码       
 public ActionResult Index()
        {
            Post[] posts = Post.FindAll();
            if (posts.Count() > 0)
            {
                ViewData["AllPost"] = posts.ToList();
            }
            return View();
        }
View Code
 <form id="form1" runat="server">
    <h2>
        Index</h2>
    <table>
        <tr>
            <td>
                Id
            </td>
            <td>
                Subject
            </td>
            <td>
                Text
            </td>
            <td>
                DateAdded
            </td>
        </tr>
        <% foreach (var post in (List<Post>)ViewData["AllPost"])
           {%>
        <tr>
            <td>
                <%:post.Id.ToString() %>
            </td>
            <td>
                <%:post.Subject %>
            </td>
            <td>
                <%:post.ShortText %>
            </td>
            <td>
                <%:post.DateAdded %>
            </td>
        </tr>
        <%} %>
    </table>
    </form>
View Code

  CRUD都是通过实体对象调用方法完成数据库的持久化。

四、通过ActiveRecord Generator生成实体类
  1)执行Castle.ActiveRecord.Generator.exe,填写别名和连接字符串。配置连接字符串的时候一定要选择允许保存密码
    
 
2)选择ActiveRecord Components面板,拖动ActiveRecord到左边的空白区域,会出现一个界面,选择我们刚才设置的数据库别名,
 
 
 
 
此后操作有选择子段,设置类名等,全部完成后界面如下:
 
  3) 选择Project菜单下的Generate Code,输入命名空间,文件设置路径,并选择所要生成代码语言。
    生成代码如下:
// 
// Generated by ActiveRecord Generator
// 
//
namespace ActiveRecordDemo
{
    using Castle.ActiveRecord;
    
    
    [ActiveRecord("Posts")]
    public class Post : ActiveRecordBase
    {
        
        private int _id;
        
        private string _subject;
        
        private string _text;
        
        private System.DateTime _dateAdded;
        
        private System.Collections.IList _comments;
        
        [PrimaryKey(PrimaryKeyType.Native)]
        public int Id
        {
            get
            {
                return this._id;
            }
            set
            {
                this._id = value;
            }
        }
        
        [Property()]
        public string Subject
        {
            get
            {
                return this._subject;
            }
            set
            {
                this._subject = value;
            }
        }
        
        [Property()]
        public string Text
        {
            get
            {
                return this._text;
            }
            set
            {
                this._text = value;
            }
        }
        
        [Property()]
        public System.DateTime DateAdded
        {
            get
            {
                return this._dateAdded;
            }
            set
            {
                this._dateAdded = value;
            }
        }
        
        [HasMany(typeof(Post), Table="Posts", ColumnKey="PostId")]
        public System.Collections.IList Comments
        {
            get
            {
                return this._comments;
            }
            set
            {
                this._comments = value;
            }
        }
        
        public static void DeleteAll()
        {
            ActiveRecordBase.DeleteAll(typeof(Post));
        }
        
        public static Post[] FindAll()
        {
            return ((Post[])(ActiveRecordBase.FindAll(typeof(Post))));
        }
        
        public static Post Find(int Id)
        {
            return ((Post)(ActiveRecordBase.FindByPrimaryKey(typeof(Post), Id)));
        }
    }
}
View Code
// 
// Generated by ActiveRecord Generator
// 
//
namespace ActiveRecordDemo
{
    using Castle.ActiveRecord;
    
    
    [ActiveRecord("Comments")]
    public class Comment : ActiveRecordBase
    {
        
        private int _id;
        
        private string _test;
        
        private string _author;
        
        private System.DateTime _dateAdded;
        
        private Post _post;
        
        [PrimaryKey(PrimaryKeyType.Native)]
        public int Id
        {
            get
            {
                return this._id;
            }
            set
            {
                this._id = value;
            }
        }
        
        [Property()]
        public string Test
        {
            get
            {
                return this._test;
            }
            set
            {
                this._test = value;
            }
        }
        
        [Property()]
        public string Author
        {
            get
            {
                return this._author;
            }
            set
            {
                this._author = value;
            }
        }
        
        [Property()]
        public System.DateTime DateAdded
        {
            get
            {
                return this._dateAdded;
            }
            set
            {
                this._dateAdded = value;
            }
        }
        
        [BelongsTo("PostId")]
        public Post Post
        {
            get
            {
                return this._post;
            }
            set
            {
                this._post = value;
            }
        }
        
        public static void DeleteAll()
        {
            ActiveRecordBase.DeleteAll(typeof(Comment));
        }
        
        public static Comment[] FindAll()
        {
            return ((Comment[])(ActiveRecordBase.FindAll(typeof(Comment))));
        }
        
        public static Comment Find(int Id)
        {
            return ((Comment)(ActiveRecordBase.FindByPrimaryKey(typeof(Comment), Id)));
        }
    }
}
View Code

注意:生成的一对多或者多对一的代码可能需要手动改造一下。

 

posted @ 2013-09-03 22:13  Lynn_  Views(526)  Comments(0Edit  收藏  举报