Click here to Skip to main content
15,886,067 members
Articles / Programming Languages / SQL
Article

Generic Class to Perform Insert/Update/Get/Delete in LINQ to SQL Generated Classes

Rate me:
Please Sign up or sign in to vote.
4.00/5 (5 votes)
12 Aug 2011CPL2 min read 24K   9   3
To create a Generic class for BLL or middle layer to perform all the basic CRUD operations on the LINQ to SQL generated classes.

This article is a sponsored article. Articles such as these are intended to provide you with information on products and services that we consider useful and of value to developers

Introduction

This article creates a Generic class which can be used to perform the basic CRUD operations in just a one line of code. The pre-requirement for this article is that we need to have a LINQ to SQL generated classes, because the generic class has been designed in such a way to perform opertion only with the LINQ to SQL generated classes.

Using the Code

A brief description of how to use the article or code. The class names, the methods and properties, any tricks or tips.

The pre-requisite for this generic class is that we should have the LINQ to SQL generated classes available. The process to generate the LINQ to SQL classes can be found here.

We will assume all the classes in the LINQ to SQL classes as the entity and also that the name of the DataContext class created is TestDBContext. So, we need to create a interface named IEntity having the generic method signatures available. The code for the interface is

C#
// C# Code
public interface IEntity<T> where T : class
{
    IList<T> List();

    IList<T> List(int? page, int? pageSize, Expression<Func<T, bool>> predicate, Expression<Func<T, object>> sort);

    void Add(T item);

    T Get(Int64 Id);

    void Update(T item);

    bool Delete(T Item);

}

To create a generic class we need to implement this interface and name it as Entity. Before creating this class we need to have some namespaces included in our class i.e.,

C#
// Namespaces included
using System.Data.Linq;
using System.Reflection;
using System.Linq.Expressions;

The main problem raised during the creating of this generic class was that different tables in the database can have their primary key column defined with different types of data types. For example, one Table might have its Primary Key defined as 'BIGINT' and another table might have defined its primary key data type with 'VARCHAR'. So, to get the data from these tables using this generic class, we need to send the column name alongwith the data type of the column. And my generic class will determine the property of the class as per the parameter defined and will return the result. The other operation on of the table were easy and needed on 2-3 lines of code.

Code for the Entity class

C#
public class Entity<T> : IEntity<T> where T : class
{

    // Inserts the data values in the LINQ to SQL generated class.
    public virtual void Add(T item)
    {
        using (TestDBContext db = new TestDBContext())
        {
            db.GetTable<T>().InsertOnSubmit(item);
            db.SubmitChanges();
        }
    }

    // Returns the list of the object of LINQ to SQL Class
    public virtual IList<T> List()
    {
        using (TestDBContext db = new TestDBContext())
        {
            return db.GetTable<T>().ToList();
        }
    }

    // Returns the list of the object of LINQ to SQL Class on the basis of parameters
    public virtual IList<T> List(int? page, int? pageSize, System.Linq.Expressions.Expression<Func<T, bool>> predicate, System.Linq.Expressions.Expression<Func<T, object>> sort)
    {
        var result = this.List().AsQueryable();

        if (predicate != null)
            result = result.Where(predicate);

        if (sort != null)
            result = result.OrderBy(sort);

        if (page.HasValue && pageSize.HasValue)
            result = result.Skip((page.Value - 1) * pageSize.Value).Take(pageSize.Value);

        return result.ToList();
    }

    // Returns the object on the basis of the objects ID, if ID datatype is Int64.
    public virtual T Get(Int64 value)
    {
        return Get(typeof(System.Int64), "ID", value);
    }

    // Returns the object on the basis of the objects ID, if ID datatype is String.
    public virtual T Get(string value)
    {
        return Get(typeof(System.String), "ID", value);
    }

    // Returns the object on the basis of the objects property column.
    public virtual T Get(Type propertyType, string propertyName, object propertyValue)
    {
        T result = null;
        using (TestDBContext db = new TestDBContext())
        {
            IQueryable<T> queryableData = db.GetTable<T>().AsQueryable<T>();
            if (queryableData != null)
            {
                ParameterExpression pe = Expression.Parameter(typeof(T), "entity");

                Expression left = Expression.Property(pe, GetPropertyInfo(propertyName));
                Expression right = Expression.Constant(propertyValue, propertyType);

                Expression predicateBody = Expression.Equal(left, right);

                MethodCallExpression whereCallExpression = Expression.Call(
                    typeof(Queryable),
                    "Where",
                    new Type[] { queryableData.ElementType },
                    queryableData.Expression,
                    Expression.Lambda<Func<T, bool>>(predicateBody, new ParameterExpression[] { pe }));

                IQueryable<T> results = queryableData.Provider.CreateQuery<T>(whereCallExpression);
                foreach (T item in results)
                {
                    result = item;
                    break;
                }
            }
            return result;
        }
    }

    // Updates the data values in the LINQ to SQL generated class.
    public virtual void Update(T item)
    {
        using (TestDBContext db = new TestDBContext())
        {
            db.GetTable<T>().Attach(item, true);
            db.SubmitChanges();
        }
    }

    // Deletes the data values in the LINQ to SQL generated class.
    public virtual bool Delete(T Item)
    {
        using (TestDBContext db = new TestDBContext())
        {
            db.GetTable<T>().DeleteOnSubmit(Item);
            db.SubmitChanges();
            return true;
        }
    }

    private PropertyInfo GetPropertyInfo(string propertyName)
    {
        PropertyInfo[] properties = typeof(T).GetProperties();
        PropertyInfo result = null;
        foreach (PropertyInfo pi in properties)
        {
            if (pi.Name.Equals(propertyName))
            {
                result = pi;
                break;
            }
        }
        return result;
    }

}

Example of calling the Entity class for CRUD operations:

C#
//Suppose we have a class named 'NOTEs' generated by the LINQ to SQL.

// Code to add the object values
NOTES obj = new NOTES();
obj.CATEGORY = 'First Category';
obj.SUBJECT = 'Subject of the Category';
obj.NODETEXT = 'Sample text of the Node';

Entity<NOTES> entity = new Entity</NOTES>();
entity.Add(obj);

// Code to get the object values
Entity<NOTES> entity = new Entity<NOTES>();
NOTES note = entity.Get(typeof(System.Int64), "ID", 1);

....

Points of Interest

How to: Create LINQ to SQL Classes
How to: Use Expression Trees

License

This article, along with any associated source code and files, is licensed under The Common Public License Version 1.0 (CPL)


Written By
Software Developer (Senior) ISTS Infotech Solutions Pvt. Ltd.
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.
This is a Collaborative Group (No members)


Comments and Discussions

 
QuestionCRUD updates Pin
Keith Redrup19-Feb-14 2:30
Keith Redrup19-Feb-14 2:30 
GeneralMy vote of 2 Pin
vahid.shirzadi17-Feb-13 1:52
vahid.shirzadi17-Feb-13 1:52 
GeneralMy vote of 4 Pin
tadeze16-Jun-12 23:31
tadeze16-Jun-12 23:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.