活动记录设计模式?

时间:2010-07-04 08:12:05

标签: database design-patterns orm oop

我最近一直在研究各种ORM框架(主要是.net),并且看到Active Record设计模式通常用于保存数据。

我只是想知道每个人对活跃记录模式的看法是什么?我个人认为它对数据对象承担了太多责任,无论是数据容器还是实体bean。我总是从一个中央控制器接近持久化对象,这个对象暴露了一个方法,比如Persist(),它接受一个接口说IEntityBean,而不是让bean对它的持久性进行排序。这也是我为人口所采用的方法我得到一个数据集并且通常填充bean而不是让bean接收数据集并填充自己。我只是不喜欢有逻辑的豆子。这是一种老式的做法还是让别人分享我的恐惧?

ORM框架如何不使用活动记录模式映射表来对象和对象表?是一个控制持续不良方法的中央控制器吗?

提前感谢您的意见!

3 个答案:

答案 0 :(得分:4)

我不使用ActiveRecord,因为 ActiveRecord违反SRP大时间。我们有自己的内部定制ORM。

修改

在我们的ORM中,我们充分利用了C#3.0功能。我们有一个名为Application.Infrastructure的库项​​目,它承载业务对象的所有基类。我们有一个验证框架和使用属性的自动映射。

ORM大量使用Attributes来自动完成大多数繁琐的任务,如映射和验证。我可以在框架中添加新功能作为新方面。

TableMapping属性将告诉我们此对象映射到哪个表。 DataFieldMapping属性将告诉我们该对象的属性映射到哪个coloumn。 validation framework允许我在指定的ValidationAttribute的帮助下验证每个字段。

每个业务对象都有一个基类EntityBase,而业务集合具有EntityCollectionBase。我们使用传统的数据集进行数据库交互,我们为EntityBase,EntityCollectionBase,DataRow和DataTable编写了扩展方法。这个exntesion方法将从对象的属性中读取映射元数据,并通过Reflection执行[双向]映射。

示例业务对象在我的应用程序中看起来像这样。

<强> User.cs

[TableMapping("Users")]
public class User : EntityBase
{
    #region Constructor(s)
    public AppUser()
    {
        BookCollection = new BookCollection();
    }
    #endregion

    #region Properties

    #region Default Properties - Direct Field Mapping using DataFieldMappingAttribute

    private System.Int32 _UserId;

    private System.String _FirstName;
    private System.String _LastName;
    private System.String _UserName;
    private System.Boolean _IsActive;

    [DataFieldMapping("UserID")]
    [DataObjectFieldAttribute(true, true, false)]
    [NotNullOrEmpty(Message = "UserID From Users Table Is Required.")]
    public override int Id
    {
        get
        {
            return _UserId;
        }
        set
        {
            _UserId = value;
        }
    }

    [DataFieldMapping("UserName")]
    [Searchable]
    [NotNullOrEmpty(Message = "Username Is Required.")]
    public string UserName
    {
        get
        {
            return _UserName;
        }
        set
        {
            _UserName = value;
        }
    }

    [DataFieldMapping("FirstName")]
    [Searchable]
    public string FirstName
    {
        get
        {
            return _FirstName;
        }
        set
        {
            _FirstName = value;
        }
    }

    [DataFieldMapping("LastName")]
    [Searchable]
    public string LastName
    {
        get
        {
            return _LastName;
        }
        set
        {
            _LastName = value;
        }
    }

    [DataFieldMapping("IsActive")]
    public bool IsActive
    {
        get
        {
            return _IsActive;
        }
        set
        {
            _IsActive = value;
        }
    }

    #region One-To-Many Mappings
    public BookCollection Books { get; set; }

    #endregion

    #region Derived Properties
    public string FullName { get { return this.FirstName + " " + this.LastName; } }

    #endregion

    #endregion

    public override bool Validate()
    {
        bool baseValid = base.Validate();
        bool localValid = Books.Validate();
        return baseValid && localValid;
    }
}

<强> BookCollection.cs

/// <summary>
/// The BookCollection class is designed to work with lists of instances of Book.
/// </summary>
public class BookCollection : EntityCollectionBase<Book>
{
    /// <summary>
    /// Initializes a new instance of the BookCollection class.
    /// </summary>
    public BookCollection()
    {
    }

    /// <summary>
    /// Initializes a new instance of the BookCollection class.
    /// </summary>
    public BookCollection (IList<Book> initialList)
        : base(initialList)
    {
    }
}

答案 1 :(得分:1)

在使用NHibernate本身进行了大量实验后,我使用了Castle ActiveRecord(基于NHibernate)。只要您没有阅读或编写大量对象,ORM方法的执行速度就足够快。

使用NHibernate,您必须通过XML文件指定映射(使其与代码保持同步非常痛苦),并且上次使用它时,可以使用代码中的Attributes来定义它们。显然,这会在代码反射和代码生成的背景下大量使用来执行所有“魔法”。通过使用ActiveRecord,我对ORM方法的可维护性感到满意。

我在Castle ActiveRecord中不喜欢的是你必须从基础ActiveRecordBase派生你的ActiveRecord类。什么有时是一个强烈的要求,因为基本上你可能想从其他东西派生它,让它只行为像ActiveRecord。有一种方法可以使用ActiveRecordMediator来避免这种情况。

我还没有使用MS解决方案的经验,因为在我需要一个他们什么都没有的时候(他们在工作框架上来得太晚了)。 Castle Project几乎提供了从控制容器反转到高级ORM的更大Web开发所需的一切。

答案 2 :(得分:0)

DataMapper更强大。

我喜欢的唯一ORM(虽然我不知道.Net)而且我认为足够灵活的是SQLAlchemy,请看一些例子。