/// <summary>
        ///     Finds the by.
        /// </summary>
        /// <param name="where">The predicate.</param>
        /// <returns></returns>
        public virtual IEnumerable <TEntity> FindBy(Expression <Func <TEntity, bool> > @where)
        {
            IEnumerable <TEntity> query;

            AppUtility.ValidateDbSet(CurrentDbSet);

            try
            {
                query = CurrentDbSet.Where(where).AsEnumerable();
            }
            catch (SqlException sqex)
            {
                Audit.Log.Error(AppConstants.ErrorMessages.SqlExceptionMessage, sqex);

                throw;
            }
            catch (DbException dbex)
            {
                Audit.Log.Error(AppConstants.ErrorMessages.DbExceptionMessage, dbex);

                throw;
            }
            catch (Exception ex)
            {
                Audit.Log.Error(AppConstants.ErrorMessages.ExceptionMessage, ex);

                throw;
            }

            return(query);
        }
        /// <summary>
        ///     Gets all.
        /// </summary>
        /// <returns></returns>
        public virtual IEnumerable <TEntity> GetAll()
        {
            AppUtility.ValidateDbSet(CurrentDbSet);

            try
            {
                return(CurrentDbSet.AsEnumerable());
            }
            catch (SqlException sqex)
            {
                Audit.Log.Error(AppConstants.ErrorMessages.SqlExceptionMessage, sqex);

                throw;
            }
            catch (DbException dbex)
            {
                Audit.Log.Error(AppConstants.ErrorMessages.DbExceptionMessage, dbex);

                throw;
            }
            catch (Exception ex)
            {
                Audit.Log.Error(AppConstants.ErrorMessages.ExceptionMessage, ex);

                throw;
            }
        }
        /// <summary>
        ///     Gets the single.
        /// </summary>
        /// <param name="where">The where.</param>
        /// <param name="navigationProperties">The navigation properties.</param>
        /// <returns></returns>
        public virtual TEntity GetSingle(Func <TEntity, bool> @where,
                                         params Expression <Func <TEntity, object> >[] @navigationProperties)
        {
            TEntity item;

            AppUtility.ValidateDbSet(CurrentDbSet);

            try
            {
                IQueryable <TEntity> dbQuery = CurrentDbContext.Set <TEntity>();

                if (navigationProperties != null)
                {
                    //Apply eager loading
                    dbQuery = navigationProperties.Aggregate(
                        dbQuery,
                        (current, navigationProperty) => current.Include(navigationProperty)
                        );
                }

                if (dbQuery == null)
                {
                    return(null);
                }

                item = dbQuery
                       .AsNoTracking()         //Don't track any changes for the selected item
                       .FirstOrDefault(where); //Apply where clause
            }
            catch (SqlException sqex)
            {
                Audit.Log.Error(AppConstants.ErrorMessages.SqlExceptionMessage, sqex);

                throw;
            }
            catch (DbException dbex)
            {
                Audit.Log.Error(AppConstants.ErrorMessages.DbExceptionMessage, dbex);

                throw;
            }
            catch (Exception ex)
            {
                Audit.Log.Error(AppConstants.ErrorMessages.ExceptionMessage, ex);

                throw;
            }

            return(item);
        }
        /// <summary>
        ///     Deletes the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        public virtual TEntity Delete(TEntity entity)
        {
            AppUtility.ValidateDbSet(CurrentDbSet);

            AppUtility.ValidateEntity(entity);

            CurrentDbContext.Entry(entity).State = EntityState.Deleted;

            var result = CurrentDbSet.Remove(entity);

            //CurrentDbContext.SaveChanges();

            return(result);
        }
        /// <summary>
        ///     Removes the many.
        /// </summary>
        /// <param name="items">The items.</param>
        public virtual void RemoveMany(params TEntity[] items)
        {
            AppUtility.ValidateDbSet(CurrentDbSet);

            if (items == null)
            {
                return;
            }

            try
            {
                foreach (var item in items)
                {
                    CurrentDbContext.Entry(item).State = EntityState.Deleted;
                    //this sets base value
                    UpdatedOn = DateTime.UtcNow;
                    //this sets model value
                    item.UpdatedOn = UpdatedOn ?? DateTime.UtcNow;

                    EntityState = EntityState.Deleted;
                }
                CurrentDbContext.SaveChanges();
            }
            catch (SqlException sqex)
            {
                Audit.Log.Error(AppConstants.ErrorMessages.SqlExceptionMessage, sqex);

                throw;
            }
            catch (DbException dbex)
            {
                Audit.Log.Error(AppConstants.ErrorMessages.DbExceptionMessage, dbex);

                throw;
            }
            catch (Exception ex)
            {
                Audit.Log.Error(AppConstants.ErrorMessages.ExceptionMessage, ex);

                throw;
            }
        }
        /// <summary>
        ///     Adds the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        public virtual TEntity Add(TEntity entity)
        {
            AppUtility.ValidateDbSet(CurrentDbSet);

            AppUtility.ValidateEntity(entity);

            try
            {
                entity.CreatedOn = DateTime.UtcNow;
                //this sets model value
                entity.CreatedOn = CreatedOn ?? DateTime.UtcNow;

                var added = CurrentDbSet.Add(entity);

                CurrentDbContext.Entry(entity).State = EntityState.Added;

                return(added);
            }
            catch (SqlException sqex)
            {
                Audit.Log.Error(AppConstants.ErrorMessages.SqlExceptionMessage, sqex);

                throw;
            }
            catch (DbException dbex)
            {
                Audit.Log.Error(AppConstants.ErrorMessages.DbExceptionMessage, dbex);

                throw;
            }
            catch (Exception ex)
            {
                Audit.Log.Error(AppConstants.ErrorMessages.ExceptionMessage, ex);

                throw;
            }
        }