码迷,mamicode.com
首页 > 数据库 > 详细

EntityFreamWork 数据库底层

时间:2015-01-12 20:59:33      阅读:1336      评论:0      收藏:0      [点我收藏+]

标签:

定义了DbRepository<TEntity>:IRepository<TEntity> ,SimpleDbContext继承了DbContext, UnitOfWork:IUnitOfWork

 public interface IDbRepository<TEntity> where TEntity : class
    {
        //基础方法
        void Add(TEntity entity);
        void Delete(System.Linq.Expressions.Expression<Func<TEntity, bool>> where);
        void Delete(TEntity entity);
        TEntity GetByKey(object id);
        IQueryable<TEntity> Table { get; }
        IQueryable<TEntity> TableNoTracking { get; }
        void Update(TEntity entity);

        //扩展方法(调用就会立即执行)
        int DeleteEx(System.Linq.Expressions.Expression<Func<TEntity, bool>> where);
        int UpdateEx(System.Linq.Expressions.Expression<Func<TEntity, bool>> filterExpression, System.Linq.Expressions.Expression<Func<TEntity, TEntity>> updateExpression);
        int UpdateEx(System.Linq.Expressions.Expression<Func<TEntity, TEntity>> updateExpression);
    }

 

 public class DbRepository<TEntity> : IDbRepository<TEntity> where TEntity : class
    {
        private SimpleDbContext _DataContext;

        private DbSet<TEntity> TModel;

        public DbRepository(SimpleDbContext db)
        {
            _DataContext = db;
            var objectContext = (_DataContext as IObjectContextAdapter).ObjectContext;
            objectContext.CommandTimeout = 300;
            TModel = _DataContext.Set<TEntity>();
        }

        #region 属性
        public IQueryable<TEntity> Table
        {
            get { return TModel.AsQueryable(); }
        }

        public IQueryable<TEntity> TableNoTracking
        {
            get { return TModel.AsNoTracking(); }
        }
        #endregion

        #region 基础方法

        public virtual TEntity GetByKey(object id)
        {
            return TModel.Find(id);
        }

        public virtual void Add(TEntity entity)
        {
            TModel.Add(entity);
        }

        public virtual void Update(TEntity entity)
        {
            if (!TModel.Local.Contains(entity))
            {
                TModel.Attach(entity);
            }
            _DataContext.Entry(entity).State = EntityState.Modified;
        }

        public virtual void Delete(TEntity entity)
        {
            TModel.Remove(entity);
        }

        public virtual void Delete(Expression<Func<TEntity, bool>> where)
        {
            IEnumerable<TEntity> objects = TModel.Where<TEntity>(where).AsEnumerable();
            foreach (TEntity obj in objects)
                TModel.Remove(obj);
        }

        //public virtual int SaveChanges()
        //{
        //    try
        //    {
        //        return _DataContext.SaveChanges();
        //    }
        //    catch (DbEntityValidationException dbEx)
        //    {
        //        var msg = string.Empty;

        //        foreach (var validationErrors in dbEx.EntityValidationErrors)
        //            foreach (var validationError in validationErrors.ValidationErrors)
        //                msg += Environment.NewLine + string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);

        //        var fail = new Exception(msg, dbEx);
        //        throw fail;
        //    }
        //}
        #endregion

        #region 扩展方法,但是操作是直接提交的 需要引用这个EntityFramework.Extensions,Nuget包(EntityFramework.Extended)

        public int UpdateEx(Expression<Func<TEntity, TEntity>> updateExpression)
        {
            return TModel.Update<TEntity>(updateExpression);
        }

        public int UpdateEx(Expression<Func<TEntity, bool>> filterExpression, Expression<Func<TEntity, TEntity>> updateExpression)
        {
            return TModel.Update(filterExpression, updateExpression);
        }

        public int DeleteEx(Expression<Func<TEntity, bool>> where)
        {
            return TModel.Delete(where);
        }
        #endregion

 

public class SimpleDbContext : DbContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
            .Where(type => !String.IsNullOrEmpty(type.Namespace))
            .Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
            foreach (var type in typesToRegister)
            {
                dynamic configurationInstance = Activator.CreateInstance(type);
                modelBuilder.Configurations.Add(configurationInstance);
            }
            base.OnModelCreating(modelBuilder);
        }


        /// <summary>
        /// Execute stores procedure and load a list of entities at the end
        /// </summary>
        /// <typeparam name="TEntity">Entity type</typeparam>
        /// <param name="commandText">Command text</param>
        /// <param name="parameters">Parameters</param>
        /// <returns>Entities</returns>
        public IList<TEntity> ExecuteStoredProcedureList<TEntity>(string commandText, params object[] parameters) where TEntity : class, new()
        {
            //add parameters to command
            if (parameters != null && parameters.Length > 0)
            {
                for (int i = 0; i <= parameters.Length - 1; i++)
                {
                    var p = parameters[i] as DbParameter;
                    if (p == null)
                        throw new Exception("Not support parameter type");

                    commandText += i == 0 ? " " : ", ";

                    commandText += "@" + p.ParameterName;
                    if (p.Direction == ParameterDirection.InputOutput || p.Direction == ParameterDirection.Output)
                    {
                        //output parameter
                        commandText += " output";
                    }
                }
            }

            var result = this.Database.SqlQuery<TEntity>(commandText, parameters).ToList();

            //performance hack applied as described here - http://www.nopcommerce.com/boards/t/25483/fix-very-important-speed-improvement.aspx
            //bool acd = this.Configuration.AutoDetectChangesEnabled;
            //try
            //{
            //    this.Configuration.AutoDetectChangesEnabled = false;

            //    for (int i = 0; i < result.Count; i++)
            //        result[i] = AttachEntityToContext(result[i]);
            //}
            //finally
            //{
            //    this.Configuration.AutoDetectChangesEnabled = acd;
            //}

            return result;
        }

        /// <summary>
        /// Creates a raw SQL query that will return elements of the given generic type.  The type can be any type that has properties that match the names of the columns returned from the query, or can be a simple primitive type. The type does not have to be an entity type. The results of this query are never tracked by the context even if the type of object returned is an entity type.
        /// </summary>
        /// <typeparam name="TElement">The type of object returned by the query.</typeparam>
        /// <param name="sql">The SQL query string.</param>
        /// <param name="parameters">The parameters to apply to the SQL query string.</param>
        /// <returns>Result</returns>
        public IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] parameters)
        {
            return this.Database.SqlQuery<TElement>(sql, parameters);
        }

        /// <summary>
        /// Executes the given DDL/DML command against the database.
        /// </summary>
        /// <param name="sql">The command string</param>
        /// <param name="doNotEnsureTransaction">false - the transaction creation is not ensured; true - the transaction creation is ensured.</param>
        /// <param name="timeout">Timeout value, in seconds. A null value indicates that the default value of the underlying provider will be used</param>
        /// <param name="parameters">The parameters to apply to the command string.</param>
        /// <returns>The result returned by the database after executing the command.</returns>
        public int ExecuteSqlCommand(string sql, bool doNotEnsureTransaction = false, int? timeout = null, params object[] parameters)
        {
            int? previousTimeout = null;
            if (timeout.HasValue)
            {
                //store previous timeout
                previousTimeout = ((IObjectContextAdapter)this).ObjectContext.CommandTimeout;
                ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = timeout;
            }

            var transactionalBehavior = doNotEnsureTransaction
                ? TransactionalBehavior.DoNotEnsureTransaction
                : TransactionalBehavior.EnsureTransaction;
            var result = this.Database.ExecuteSqlCommand(transactionalBehavior, sql, parameters);

            if (timeout.HasValue)
            {
                //Set previous timeout back
                ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = previousTimeout;
            }

            //return result
            return result;
        }
public interface IUnitOfWork : IDisposable
    {
        int Commit();
        IDbRepository<TEntity> GetRepository<TEntity>() where TEntity : class;
    }
  public class UnitOfWork : IUnitOfWork
    {
        private SimpleDbContext _simpleDbContext;
        private Dictionary<Type, object> repositoryCache = new Dictionary<Type, object>();

        public UnitOfWork()
        {
            _simpleDbContext = new SimpleDbContext();
        }

        public int Commit()
        {
           try
           {
               return _simpleDbContext.SaveChanges();
           }
           catch (DbEntityValidationException dbEx)
           {
               var msg = string.Empty;

               foreach (var validationErrors in dbEx.EntityValidationErrors)
                   foreach (var validationError in validationErrors.ValidationErrors)
                       msg += Environment.NewLine + string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);

               var fail = new Exception(msg, dbEx);
               throw fail;
           }
        }

        public void Dispose()
        {
            this._simpleDbContext.Dispose();
        }


        public IDbRepository<TEntity> GetRepository<TEntity>() where TEntity : class
        {
            if (repositoryCache.ContainsKey(typeof(TEntity)))
            {
                return (IDbRepository<TEntity>)repositoryCache[typeof(TEntity)];
            }
            IDbRepository<TEntity> repository = new DbRepository<TEntity>(_simpleDbContext);
            this.repositoryCache.Add(typeof(TEntity), repository);
            return repository;
        }
    }

 

EntityFreamWork 数据库底层

标签:

原文地址:http://www.cnblogs.com/ZHUYIN/p/4219572.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!