Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / All-Topics

Active Record pattern

0.00/5 (No votes)
22 Sep 2014CPOL2 min read 19.6K  
Prerequisites :    ORM’s This is a kind of Persistence Patterns . Now why do we need these kind of patterns ? When building a complex application , you tend to divide the application into UI , Middle tier and the Database .

Prerequisites :    ORM’s

This is a kind of Persistence Patterns .

Now why do we need these kind of patterns ?
When building a complex application , you tend to divide the application into UI , Middle tier and the Database . When building applications like WPF, their is a general suggestion that your ViewModel should be a direct replica of your View , thus you will be able to replicate all the actions directly using the ViewModel itself.
Similarly it is advised that your Model should reflect the schema of your Database table , with validations and translations attached to this . During such scenarios there arises a need to persist the state of the Business objects between sessions .

Whilst using any ORM to map data from business entities to tables, you internally will be using few patterns . Before analyzing which strategy suits your application using ORM, it is best advised to understand the underlying patterns that would give a broader picture .

As spoken earlier , we require the model class to replicate the database so that the data can easily flow between the application and the database . Thus considering the example of Address class we will move further .

public class Address
   {
       public long Id { get; set; }
       public string Address1 { get; set; }
       public string Address2 { get; set; }
       public string City { get; set; }
       public string StateOrProvince { get; set; }
       public string Country { get; set; }
       public string PostalCode { get; set; }
       public string TimeZone { get; set; }
   }

you can go ahead and use any mapping technique . You can write your own Mapper class or you can use any of the existing . I am using existing FluentHibernate dlls for the same . You can use NUGET and download these dlls.

Find below the mapping class

using FluentNHibernate.Mapping;
using NHibernate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ORM
{
    public class AddressMap : ClassMap<Address>
    {
        public AddressMap()
        {          

            Table("Address");
            Map(x => x.Address1).Column("Id");
            Map(x => x.Address1).Column("address1");
            Map(x => x.Address2).Column("address2");
            Map(x => x.City).Column("city");
            Map(x => x.StateOrProvince).Column("province_code");
            Map(x => x.Country).Column("country_name");
            Map(x => x.PostalCode).Column("postal_code");
        }
    }
}

Now coming to the Active record pattern. We will allow in our ORM to keep the responsibility of creating the mapping to the model class itself. You can choose a different Mapping class as stated above depending on the complexity of the application. I am assuming to be a low complex application and thus use the Active record pattern.

The object wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data. An Active Record approach puts persistence methods directly onto the entity object. In this case, the Address class would probably have methods like Save, Update, and Delete, as well as a static Load method that queries the database for an Address object.

The typical usage of the Active Record pattern is to essentially make a strongly typed class wrapper around a single row in a database table. As such, the Active Record classes are generally an exact mirror of the database structure (this will vary between tools). Many Active Record implementations will generate the entity objects directly from the database structure.

A generic implementation is shown below :

Proper addres class

 public class Address
    {
        public long Id { get; set; }
        public string Address1 { get; set; }
        public string Address2 { get; set; }
        public string City { get; set; }
        public string StateOrProvince { get; set; }
        public string Country { get; set; }
        public string PostalCode { get; set; }
        public string TimeZone { get; set; }

        public static Address GetAddress(string columnName, string value)
        {

            //below query will get only a value from DB
            var sqlQuery = "SELECT * FROM Address WHERE "+columnName+" = '"+value+"' LIMIT 1;";

            //get value from DB

            Address record = new Address();
           //fill this address using the returned value and then return 

            return record;

        }

        public bool Create()
        {
            //write code to create current address record           

            var sql = "INSERT INTO Address VALUES ('" + Address1 + "', '" + Address2 + "');";
            // if create success then return true , else false;
            return true;
        }

        public bool Update()
        {
            //write code to update current address record
            // if update success then return true , else false;
            return true;
        }

        public bool Delete()
        {
            //write code to delete current address record
            // if delete success then return true , else false;
            return true;
        }
    }
}

as you can see we have individual implementations of all CRUD operations also we have a static method to return values depending on some criteria .

The call can happen as below ,

public void AddressRecord()
       {
           Address addobj = new Address();
           addobj.Address1 = "XYZ";
           addobj.City = "Pune";
           addobj.Country = "India";
           addobj.StateOrProvince = "MAH";
           addobj.Create();

       }

We will be seeing another underlying method of Data Mapper in the next blog .

 


License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)