Wednesday, 20 November 2013

Generic Repositories for Entity Framework 4 and Entity Framework 5 & 6


The basic difference between Entity Framework 4 and Entity Framework 5 or 6 is the use of DbContext rather than Object Context. The additional features provided by the DbContext over the ObjectContext are really helpful in handling different scenarios while performing database operations.

Recently I worked on designing  generic repositories for both EF4 and EF5. I am sharing below my code for generic repository implementation for Entity Framework 5.0 and 6.0 as well as Entity Framework 4.0.

---------------------------------------IRepository--------------------------------------------------------------------
Namespace used:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Data;
using System.Data.Entity;

-------------------------------------------------------------

    public interface IRepository<TEntity> : IDisposable where TEntity : class
    {
        DbSet<TEntity> GetDbSet();

        IEnumerable<TEntity> GetAll();
        IEnumerable<TEntity> GetEntity(List<string> relatedEntities);
        void SetEntityState(object entity, EntityState entityState);
        TEntity GetById(object id);
        IEnumerable<TEntity> GetEntity(Expression<Func<TEntity, bool>> filter, List<string> relatedEntities);
        TEntity Create(TEntity entity);
        TEntity Update(TEntity entityToUpdate);
        void Delete(object id);
        void Delete(TEntity entityToDelete);
    }


-----------------------------------------Repository-------------------------------------------------------------------
  public abstract class Repository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        #region Members

        private bool disposed = false;
        protected DbContext context;

        #endregion
        #region Ctor
        public Repository(DbContext context)
        {
            this.context = context;
        }

        #endregion
        public virtual DbSet<TEntity> GetDbSet()
        {
            try
            {
                return this.context.Set<TEntity>();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public IEnumerable<TEntity> GetAll()
        {
            try
            {
                return this.GetDbSet().ToList();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public IEnumerable<TEntity> GetEntity(List<string> relatedEntities)
        {
            try
            {
                IQueryable<TEntity> query = this.context.Set<TEntity>();
                if (relatedEntities != null && relatedEntities.Count() > 0)
                {
                    foreach (var relatedEntity in relatedEntities)
                    {
                        query = query.Include(relatedEntity);
                    }
                }
                return query.ToList();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void SetEntityState(object entity, System.Data.EntityState entityState)
        {
            try
            {
                this.context.Entry(entity).State = entityState;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public TEntity GetById(object id)
        {
            try
            {
                return this.context.Set<TEntity>().Find(id);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public IEnumerable<TEntity> GetEntity(Expression<Func<TEntity, bool>> filter, List<string> relatedEntities)
        {
            try
            {
                IQueryable<TEntity> query = this.context.Set<TEntity>();
                if (relatedEntities != null && relatedEntities.Count() > 0)
                {
                    foreach (var relatedEntity in relatedEntities)
                    {
                        query = query.Include(relatedEntity);
                    }
                }
                return query.Where(filter).ToList();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public TEntity Create(TEntity entity)
        {
            try
            {
                TEntity newEntity = this.context.Set<TEntity>().Add(entity);
                return newEntity;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void SaveEntity(TEntity entity)
        {
            using (var transaction = new TransactionScope(TransactionScopeOption.RequiresNew,
               new TransactionOptions()
               {
                   IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted
               }))
            {
                try
                {
                    DbSet<TEntity> dbSet = GetDbSet();
                    dbSet.Add(entity);
                    foreach (DbEntityEntry<TEntity> entry in context.ChangeTracker.Entries<TEntity>())
                    {
                        TEntity entityItem = entry.Entity;
                        DT.EntityBase entityBase = entityItem as DT.EntityBase;
                        EntityState state = EntityStateMapper.GetEntityState(entityBase);
                        entry.State = state;
                    }
                    context.SaveChanges();
                    transaction.Complete();
                }
                catch (Exception ex)
                {
                    throw (ex);
                }
            }
        }

        public TEntity Update(TEntity entityToUpdate)
        {
            try
            {
                TEntity updatedEntity = this.context.Set<TEntity>().Attach(entityToUpdate);
                context.Entry(entityToUpdate).State = EntityState.Modified;
                return updatedEntity;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void Delete(object id)
        {
            try
            {
                TEntity entityToDelete = this.context.Set<TEntity>().Find(id);
                Delete(entityToDelete);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void Delete(TEntity entityToDelete)
        {
            try
            {
                if (context.Entry(entityToDelete).State == EntityState.Detached)
                {
                    this.context.Set<TEntity>().Attach(entityToDelete);
                }
                this.context.Set<TEntity>().Remove(entityToDelete);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        protected void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    context.Dispose();
                }

            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

    }
--------------------------------------------------------------------------------------------------------------------------
 
However for Entity Framework 4 we need to use ObjectContext and our generic repository can be as below
---------------------------------------IRepository---------------------------------------------------------------------
Namespace used:using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Data.EntityClient;
using System.Data.Objects;
using System.Data.Objects.
DataClasses;
using System.Linq;

-------------------------------------------------------------
 
public interface IRepository<TEntity> where TEntity : class
    {
        IQueryable<TEntity> Get();

        IEnumerable<TEntity> GetAll();
        IEnumerable<TEntity> Find(Func<TEntity, bool> condition);
        TEntity Single(Func<TEntity, bool> condition);
        void Add(TEntity entity);
        void Update(TEntity entity);
        void Delete(TEntity entity);
        void Delete(Func<TEntity, bool> condition);
    }

 ---------------------------------------Repository--------------------------------------------------------------------

  public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        internal ObjectContext context;

        internal IObjectSet<TEntity> objectSet;
        public Repository()
        {
        }

        public Repository(ObjectContext context)
        {
            this.context = context;
            this.objectSet = context.CreateObjectSet<TEntity>();
        }

        public IQueryable<TEntity> Get()
        {
            return objectSet;
        }

        public IEnumerable<TEntity> GetAll()
        {
            return Get().AsEnumerable();
        }

        public virtual IEnumerable<TEntity> Find(Func<TEntity, bool> condition)
        {
            return objectSet.Where(condition);
        }

        public TEntity Single(Func<TEntity, bool> condition)
        {

            return objectSet.Single(condition);
        }
        public void Add(TEntity entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            objectSet.AddObject(entity);
        }

        public void Update(TEntity entity)
        {
            objectSet.Attach(entity);
        }

        public void Delete(TEntity entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            objectSet.DeleteObject(entity);
        }

        public void Delete(Func<TEntity, bool> condition)
        {
            IEnumerable<TEntity> records = from x in objectSet.Where(condition) select x;
            foreach (TEntity record in records)
            {
                objectSet.DeleteObject(record);
            }
        }

    }

No comments:

Post a Comment