Castle ActiveRecord框架學習(一)


一、Active Record(活動記錄)模式

  Active Record是業務邏輯層中(《企業應用架構模式》將該模式歸為數據源模式)常用的一種框架模式,尤其在底層數據庫模型匹配業務模型時它特別有用,它是一種以數據庫驅動為主的框架模式。

  通常,數據庫中的每張表都對應一個業務對象。業務對象表示表中的一行,並且包含數據、行為以及持久化該對象的工具,此外還有添加新實例和查找對象集合所需的方法。

  在Active Record模式中,每個業務對象均負責自己的持久化和相關的業務邏輯。

  Active Record模式非常適用於在數據模型與業務模型之間具有 一對一映射關系的簡單應用程序,如博客或論壇。

  因為業務對象與數據庫中的表具有一對一映射關系,而且均具有相同的CRUD方法,所以可以使用代碼生成器自動生成業務模型。

  Active Record模式中的對象通常會包含用來執行數據庫操作的CRUD操作,還有相關驗證及業務相關的計算和檢查功能。

  特別地,典型的Active Record類還包含一些表示數據表中的列的實例屬性和操作於當前對象上的實例方法。Active Record類中還可能包含一些靜態方法,用來操作數據表上的所有記錄。(下面的實戰操作可能會很好的幫助你理解這句話)

  1.Active Record的優勢

  Active Record的成功依賴於兩個因素:簡單和框架。Active Record概念上理解起來十分的簡單, 不過若手工實現,仍然需要很多代碼。

  編寫並維護每一個類都需要大量的代碼,不過這僅僅是最低的需求,因為你可能還要考慮為每個類或者數據表添加一個或多個數據遷移對象(DTO)。

  不可否認,活動記錄確實在簡單和最終系統的強大方面找到了良好的平衡。且該模式也等到了很多開發商的支持,例如,LINQ-to-SQL和我們今天的主角--Castle ActiveRecord

  2.Active Record的劣勢

  理論上,開發中還需要一個額外的層存在於對象模型和數據模式之間,通常叫做數據映射層(Data Mapper)。在Active Record中,我們可以將該層直接集成在對象中,不過隨着這一層越來越復雜,維護成本也在逐漸提高。

  Active Record的另外一個問題是對象和數據表設計之間的綁定。若你不得不修改數據庫,那么要同時修改Active Record的對象模型以及所有的相關代碼。

  3.Active Record與表模式的區別

  表模式通常就是目前三層框架中流行的以DateTable和DateSet為載體在各層中傳遞數據,Active Record則是以對象模型、泛型(IList<Post>)為載體在各層中傳遞數據。

二、Castle ActiveRecord介紹

  Castle ActiveRecord 是ActiveRecord 模式的一個實現,Castle ActiveRecord依賴Nhibernate來完成實際的映像。與單純的ActiveRecord 相比,Castle ActiveRecord具有以下特點:

  •  敏捷開發(它盡可能多地處理了映射和推斷,因此,對你的方案而言,當一些東西發生變化的時候,你不必去鑽研文檔或者處理大量的xml文檔)
  • 預定了像Create, Update, Save, Delete這樣的公共方法。
  • 容易實現像Find, FindAll, FindByName等此類的方法。
  • 繪畫和事務范圍(Session and transaction scopes that abstracts the ISession and translates them to a more natural idiom )

  使用Nhibernate,你繁瑣的配置工作多於復雜的映射,而使用ActiveRecord卻是推進你的生產力的一個保證,你不必再為編寫繁冗復雜的映射文件而頭疼,ActiveRecord封裝了NHibernate的操作,使用特性來代替映射文件,無論何時你需要,ActiveRecord都能給你一個Isession實例,它提供的簡潔的O/R映射會讓你為實現持久化數據層是那么簡單而驚嘆!

  官方網址:http://www.castleproject.org/

三、Castle ActiveRecord入門實戰

  環境:Windows 8.1+Visual Stidio 2013+Sql Server 2008R2+.Net Framework 4.0

  版本:Castle.ActiveRecord-3.0.RC

  相關下載:SDK下載 源碼下載

  數據庫:ActiveRecord_Blog

  數據表:Post

USE [ActiveRecord_Blog]
GO

/****** Object:  Table [dbo].[Post]    Script Date: 11/08/2014 11:12:03 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Post](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Subject] [nvarchar](64) NULL,
    [Text] [nvarchar](1024) NULL,
    [DateAdded] [datetime] NULL,
 CONSTRAINT [PK_Posts] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

  數據表:Comment

USE [ActiveRecord_Blog]
GO

/****** Object:  Table [dbo].[Comment]    Script Date: 11/08/2014 11:11:22 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Comment](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Text] [nvarchar](1024) NULL,
    [Author] [nvarchar](64) NULL,
    [DateAdded] [datetime] NULL,
    [PostId] [int] NULL,
 CONSTRAINT [PK_Comment] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Comment]  WITH CHECK ADD  CONSTRAINT [FK_Comment_Post] FOREIGN KEY([PostId])
REFERENCES [dbo].[Post] ([Id])
GO

ALTER TABLE [dbo].[Comment] CHECK CONSTRAINT [FK_Comment_Post]
GO

  如圖:

  

  項目目錄:

  

  Model-->Castle.ActiveRecord.dll、NHibernate.dll

  Web-->Model、Castle.ActiveRecord-3.0.RC中的所有DLL

  Model中:

  Post類:

    // 指定數據表
    [ActiveRecord("Post")]
    public class Post : ActiveRecordBase<Post>
    {
        // 指定數據表中的主鍵
        [PrimaryKey(PrimaryKeyType.Identity, "Id")]
        public int Id { get; set; }

        // 指定數據表中的列
        [Property("Subject")]
        public string Subject { get; set; }

        [Property("Text")]
        public string Text
        {
            get;
            set;
        }

        [Property("DateAdded")]
        public DateTime DateAdded { get; set; }

        //一對多
        [HasMany(typeof(Comment), Table = "Comment", ColumnKey = "PostId")]
        public IList<Comment> Comments { get; set; }

        // 靜態方法,通過主鍵ID查找
        public static Post Find(int id)
        {
            return FindByPrimaryKey(id);
        }
    }    

  Comment類:

    [ActiveRecord("Comment")]
    public class Comment : ActiveRecordBase<Comment>
    {
        [PrimaryKey("Id")]
        public int Id { get; set; }

        [Property("Author")]
        public string Author { get; set; }

        [Property("Text")]
        public string Text { get; set; }

        [Property("DateAdded")]
        public DateTime DateAdded { get; set; }

        [Property("PostId")]
        public int PostId { get; set; }
        // 多對一,對應Post的的Comments屬性
        [BelongsTo(Column = "PostId")]
        public Post Post { get; set; }
    }

  Web中:

  NHibernate.config配置文件:

<?xml version="1.0" encoding="utf-8"?>
<activerecord isWeb="true">
  <config>
    <add
      key="connection.driver_class"
      value="NHibernate.Driver.SqlClientDriver" />
    <add
      key="dialect"
      value="NHibernate.Dialect.MsSql2005Dialect" />
    <add
      key="connection.connection_string"
      value="UID=sa;Password=123456;Initial Catalog=ActiveRecord_Blog;Data Source=." />
    <add
      key="connection.provider"
      value="NHibernate.Connection.DriverConnectionProvider" />
    <add 
      key="proxyfactory.factory_class" 
      value="NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle" />
  </config>
</activerecord>

  Global.asax:加載配置文件

        void Application_Start(object sender, EventArgs e)
        {
            // 在應用程序啟動時運行的代碼
            AuthConfig.RegisterOpenAuth();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            InitActiveRecord();
        }

        private void InitActiveRecord()
        {
            try
            {
                string NHibernateFilePath = Server.MapPath("~/NHibernate.config");
                XmlConfigurationSource source = new XmlConfigurationSource(NHibernateFilePath);
                ActiveRecordStarter.Initialize(source, typeof(Model.Post), typeof(Model.Comment));
            }
            catch (Exception)
            {

                throw;
            }

        }

  Default.aspx:測試

  Add操作:

public void Add()
{
     Model.Post post = new Model.Post()
     {
         Subject = "測試2",
         Text = "測試內容2",
         DateAdded = DateTime.Now
      };
       post.Create();
}

  Update操作:

public void Update()
{
      Model.Post post = new Model.Post();
      post = Model.Post.Find(1);
      post.Subject = "修改后1";
      post.Text = "修改后內容1";
      post.Update();
}

  Delete操作:

public void Delete(int id)
{
    Model.Post post = new Model.Post();
    post.Id = 1;
    post.Delete();
    Response.Write("刪除了ID:" + id + "\n\r");
}

public void DeleteAll()
{
    Model.Post.DeleteAll();
}

  Find操作:

public void Find(int id)
{
    using (new SessionScope())
    {
        Model.Post post = new Model.Post();
        post = Model.Post.Find(id);
        Response.Write(post.Id.ToString() + "\n\r");
        Response.Write(post.Subject + "\n\r");
        Response.Write(post.Text + "\n\r");
        Response.Write(post.DateAdded.ToString() + "\n\r");
        Response.Write(post.Comments.FirstOrDefault().Id);
    }
}

public void FindAll()
{
     IList<Model.Post> postList = Model.Post.FindAll();
     foreach (var post in postList)
     {
          Response.Write(post.Id.ToString() + "\n\r");
          Response.Write(post.Subject + "\n\r");
          Response.Write(post.Text + "\n\r");
          Response.Write(post.DateAdded.ToString() + "\n\r");
       }
}

源碼下載:百度雲

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM