Checking Object State before Updating Database

Mouli
Posted by in C# category on for Intermediate level | Views : 5965 red flag

This article provides different approaches to check whether the object state is changed before updating the information in the data store. Examples and concepts are all related C# .Net.

Introduction

Often in the enterprise world, domain entities are represented as objects with the data encapsulated in it. These data are persisted in the data store using data access layer.

 

Most of the applications make updates to the data store. When the user changes data in the user interface, Presentation layer updates the domain model and the business objects in turn updates the data store through Data access components. During this process there are no checks made whether the data has changed. Without this check, DML Queries are run against the data store to update the information. This leads into unnecessary network calls.

 

This article provides different approaches to check whether the object state is changed before updating the information in the data store.

 

Checking the Object State

Simplest approach would be having a Boolean member in the class which denotes whether that object instance has changed since the last time it was loaded. Each accessors / mutators will set this member to true if the value was changed.

 

Below code snippet, explains how to implement this approach.

 

public class Employee

{

    private int iEmpID;

    private string strEmployeeName;

    private int iAge;

    private bool bObjectState;

 

public bool ObjectState

{

    get

    {

        return bObjectState;

    }

    set

    {

        bObjectState = value;

    }

}

    public int EmpID

    {

        get

        {

            return iEmpID;

        }

        set

        {

            if (value != iEmpID)

                bObjectState = true;

 

            iEmpID = value;

        }

    }

 

    public string EmployeeName

    {

        get

        {

            return strEmployeeName;

        }

        set

        {

            if (value != null && value != strEmployeeName)

                bObjectState = true;

 

            strEmployeeName = value;

        }

    }

 

    public int Age

    {

        get

        {

            return iAge;

        }

        set

        {

            if (value != iAge)

                bObjectState = true;

 

            iAge = value;

        }

    }

 

      // ... Methods goes here

}

 

One problem in the above approach is that, it does not tell what property was changed. To know what value got changed, we need to maintain the entire snapshot of the object state that was before updating.

 

We can use Serialization techniques to store the object state in bytes and later comparing the modified object with the one in the serialized state.

 

Serialization is the process of converting an object into a stream of bytes and persist them in memory, database or a file. De-Serialization is the process of bringing back the stored form in to the type it was representing. Serialization comes with 2 flavors.

  1. Binary Serialization - uses binary encoding
  2. XML Serialization – uses XML Streams by conforming to the schema (XSD)

 

To maintain the object state and later de-serializing to the object state, binary encoding would be the opt choice. XML Serialization would add additional headache of XML Parsing.

 


Following Code snippet were added to the Employee class for serialization and de-serialization process.

 

using System.IO;

using System.Runtime.Serialization.Formatters.Binary;

 

    // returns the stream array of the object state

    public byte[] SerializeObject()

    {

        using (MemoryStream ms = new MemoryStream())

        {

            BinaryFormatter binF = new BinaryFormatter();

            binF.Serialize(ms, this);

            ms.Position = 0;

            return ms.ToArray();

        }

    }

 

    // Decodes the object state from the binary representation

      public T Deserialize<T>(byte[] state)

    {

        using (MemoryStream ms = new MemoryStream(state))

        {

            BinaryFormatter binF = new BinaryFormatter();

            return (T) binF.Deserialize(ms);

        }

    }

 

Remember to apply the SerializableAttribute attribute ([Serializable()]) to the Employee class to indicate that instances of this type can be serialized.

 

We have added methods to take the snapshot of the object state and converting them back to the type of the object it belongs to.

 

Below Code snippet shows how the client code will use above serialization methods.

 

Employee emp = new Employee();

emp.EmpID = 0000;

emp.EmployeeName = "Chandra";

emp.Age = 33;

 

byte[] empState = emp.SerializeObject();

Employee EmpSerialized = emp.Deserialize<Employee>(empState);

Console.WriteLine(EmpSerialized.EmployeeName);

 

 

How do we compare the object that is serialized with the new modified state of the object? I would prefer using IComparable interface to compare the two instances. We need to implement type-specific comparison method. 

 

Below code snippet shows the CompareTo() Implementation for the Employee. This method uses Reflection techniques to get all properties and fields from the type.  Then it compares the value of each member with the other instances’ member.

 

 

 

// Implementing the CompareTo method of IComparable interface.

public int CompareTo(Employee otherInstance)

{

   

    int iCompareValue = 0; // default to 0 if everything is okay

 

    // comparing both Properties and Fields that are in Public scope

    PropertyInfo[] properties = typeof(Employee).GetProperties();

    FieldInfo[] fields = typeof(Employee).GetFields();

   

    // below code uses reflection to take each property / field value from the modified instance and compare with the

    // old instance. This again uses CompareTo of the underlying type of the property or field.

    foreach (PropertyInfo property in properties)

    {

        if (property.Name.ToUpper().Contains("MODIFIEDFIELDS"))

            continue;

 

        int iPropCompareValue = 0;

 

        IComparable valModifiedInstance = property.GetValue(this, null) as IComparable;

        if (valModifiedInstance == null)

            continue;

 

        object valOldInstance = property.GetValue(otherInstance, null);

       

        iPropCompareValue = valModifiedInstance.CompareTo(valOldInstance);

        if (iPropCompareValue != 0)

        {

            kvpModifiedFields.Add(property.Name, valOldInstance);

            iCompareValue = iPropCompareValue;

        }

    }

 

    foreach (FieldInfo field in fields)

    {

        if (field.Name.ToUpper().Contains("MODIFIEDFIELDS"))

            continue;

 

        int iFieldCompareValue = 0;

 

        IComparable valModifiedInstance = field.GetValue(this) as IComparable;

        if (valModifiedInstance == null)

            continue;

 

        object valOldInstance = field.GetValue(otherInstance);

 

        iFieldCompareValue = valModifiedInstance.CompareTo(valOldInstance);

        if (iFieldCompareValue != 0)

        {

            kvpModifiedFields.Add(field.Name, valOldInstance);

            iCompareValue = iFieldCompareValue;

        }

    }

    return iCompareValue;

}

 

 

Below code snippet shows how the client will initiate the compare operation.

 

// Creating a new Employee object

Employee emp = new Employee();

emp.EmpID = 1111;

emp.EmployeeName = "Chandra";

emp.Age = 33;

 

// Serializing the object in memory.

byte[] empState = emp.SerializeObject();

 

// Moldifying the Employee ID

emp.EmpID = 3235;

 

// De-Serializing before comparing

Employee EmpSerialized = emp.Deserialize<Employee>(empState);

 

int iCompareValue = emp.CompareTo(EmpSerialized);

 

if (iCompareValue != 0)

{

    Console.WriteLine("Object state has changed!!!!");

 

    foreach (KeyValuePair<string, object> kvp in emp.ModifiedFields)

    {

        Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);

    }

}

 

 

Following output will be generated.

 

 


Complete Employee Class is given below.

 

 

[Serializable()]

public class Employee : IComparable<Employee>

{

    private int iEmpID;

    private string strEmployeeName;

    private int iAge;

    private bool bObjectState;

    private Dictionary<string, object> kvpModifiedFields = new Dictionary<string, object>();

 

    public Dictionary<string, object> ModifiedFields

    {

        get

        {

            return kvpModifiedFields;

        }

    }

 

    public bool ObjectState

    {

        get

        {

            return bObjectState;

        }

        set

        {

            bObjectState = value;

        }

    }

 

    public int EmpID

    {

        get

        {

            return iEmpID;

        }

        set

        {

            if (value != iEmpID)

                bObjectState = true;

 

            iEmpID = value;

        }

    }

 

    public string EmployeeName

    {

        get

        {

            return strEmployeeName;

        }

        set

        {

            if (value != null && value != strEmployeeName)

                bObjectState = true;

 

            strEmployeeName = value;

        }

    }

 

    public int Age

    {

        get

        {

            return iAge;

        }

        set

        {

            if (value != iAge)

                bObjectState = true;

 

            iAge = value;

        }

    }

 

    // returns the stream array of the object state

    public byte[] SerializeObject()

    {

        using (MemoryStream m = new MemoryStream())

        {

            BinaryFormatter f = new BinaryFormatter();

            f.Serialize(m, this);

            m.Position = 0;

            return m.ToArray();

        }

    }

 

    // Decodes the object state from the binary representation

    public T Deserialize<T>(byte[] state)

    {

        using (MemoryStream m = new MemoryStream(state))

        {

            BinaryFormatter f = new BinaryFormatter();

            return (T)f.Deserialize(m);

        }

    }

 

    // Implementing the CompareTo method of IComparable interface.

    public int CompareTo(Employee otherInstance)

    {

       

        int iCompareValue = 0; // default to 0 if everything is okay

 

        // comparing both Properties and Fields that are in Public scope

        PropertyInfo[] properties = typeof(Employee).GetProperties();

        FieldInfo[] fields = typeof(Employee).GetFields();

       

        // below code uses reflection to take each property / field value from the modified instance and compare with the

        // old instance. This again uses CompareTo of the underlying type of the property or field.

        foreach (PropertyInfo property in properties)

        {

            if (property.Name.ToUpper().Contains("MODIFIEDFIELDS"))

                continue;

 

            int iPropCompareValue = 0;

 

            IComparable valModifiedInstance = property.GetValue(this, null) as IComparable;

            if (valModifiedInstance == null)

                continue;

 

            object valOldInstance = property.GetValue(otherInstance, null);

           

            iPropCompareValue = valModifiedInstance.CompareTo(valOldInstance);

            if (iPropCompareValue != 0)

            {

                kvpModifiedFields.Add(property.Name, valOldInstance);

                iCompareValue = iPropCompareValue;

            }

        }

 

        foreach (FieldInfo field in fields)

        {

            if (field.Name.ToUpper().Contains("MODIFIEDFIELDS"))

                continue;

 

            int iFieldCompareValue = 0;

 

            IComparable valModifiedInstance = field.GetValue(this) as IComparable;

            if (valModifiedInstance == null)

                continue;

 

            object valOldInstance = field.GetValue(otherInstance);

 

            iFieldCompareValue = valModifiedInstance.CompareTo(valOldInstance);

            if (iFieldCompareValue != 0)

            {

                kvpModifiedFields.Add(field.Name, valOldInstance);

                iCompareValue = iFieldCompareValue;

            }

        }

        return iCompareValue;

    }

 

 

 

}

 

 

 

Employee class has exposed a property called “ModifiedFields” as a collection of modified values on the object instance from the initial loading. This can be used for storing audit information, authorization etc.


Page copy protected against web site content infringement by Copyscape

About the Author

Mouli
Full Name: Chandramouli Muralidaran
Member Level: Starter
Member Status: Member
Member Since: 9/18/2009 3:13:35 AM
Country:

http://www.dotnetfunda.com
Experienced, multi-skilled, fast track performer with over 10 Years of professional experience in Design, Development and Implementation of software solutions with a special focus on .Net & J2EE technologies. Strong experience in the architecture, design and development of web-based, client-server and stand-alone applications. Key strengths include bigger picture view, conceptual depth, strong analytical and problem-solving skills.

Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)