Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Active Record Design Pattern?

I've been looking into various ORM frameworks lately (mostly .net) and see that the Active Record design pattern is commonly used to persist data.

I just wondered what everyone's take on the active record pattern is? Personally I think it puts too much responsibility on the data object, be it just a data container or an entity bean. I have always approached persisting objects from a central controller that exposes a method such as Persist() that takes in an interface say IEntityBean rather than letting the bean sort it's persistence out. This is also the approach I take for population I get a dataset and generically populate the bean rather than letting the bean take in the dataset and populate itself. I just don't like beans having logic. Is this an old fashioned approach or do other share my fears?

How do ORM frameworks that don't use the active record pattern mapping tables to object and object to tables? Is a central controller that controls persisting a bad approach?

Thanks for your opinions in advance!

like image 690
Jon Avatar asked Jul 04 '10 08:07

Jon


1 Answers

I don't use ActiveRecord because ActiveRecord violates SRP big time. we have our own inhouse custom made ORM.

EDIT

In our ORM we heavily leverage from C# 3.0 features. We have a library project called Application.Infrastructure that hosts all bases classes for our business objects. We have a validation framework and automatic mapping using attributes.

The ORM heavily uses Attributes to automate most of the tedious tasks like mapping and validation. I can add new feature as new aspect in the framework.

The TableMapping attribute will let us know which table this object maps to. The DataFieldMapping attribute will let us know which coloumn the property of theobject object maps to. The validation framework lets me validate each field with the help of designated ValidationAttribute.

Each business-object has a base class EntityBase and, business-collections have EntityCollectionBase. We use traditional data-sets for database interaction and we have written extension method for EntityBase, EntityCollectionBase, DataRow and DataTable. This exntesion methods will read the mapping meta-data from an object's attributes and perform [two-way] mapping via Reflection.

A sample business object would look like this in my application.

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)
    {
    }
}
like image 133
this. __curious_geek Avatar answered Sep 24 '22 13:09

this. __curious_geek