EntityFreamWork6.0 数据库底层访问封装

最近看了很多网络上面的很多人写的数据库底层,所以就复制和整理了他们的代码自己拼凑了一个,特意写下了来,希望看到博客的大哥们给提点意见。因为感觉写完以后思路很乱。

代码结构如下

SimpleDbContext,SimpleDbContext : DbContext,ISimpleDbContext

DbRepository,DbRepository<T> : IDbRepository<T> where T : class

UnitOfWork ,UnitOfWork : IUnitOfWork

在项目的逻辑层 我打算使用UnitOfWork,UnitofWork有方法可以获取到所有的Repository对象。但是感觉整体好像是把DBContext 封装成了UnitOfwork,好像是重复的工作一样。所以希望看到博客的

大哥们,可以给我一些修改的建议。非常感谢!

    public interface ISimpleDbContext
    {
        /// <summary>
        /// Save changes
        /// </summary>
        /// <returns></returns>
        int SaveChanges();

        /// <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>
        IList<TEntity> ExecuteStoredProcedureList<TEntity>(string commandText, params object[] parameters)
            where TEntity : class, new();

        /// <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>
        IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] 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>
        int ExecuteSqlCommand(string sql, bool doNotEnsureTransaction = false, int? timeout = null, params object[] parameters);
    }
 public class SimpleDbContext : DbContext,ISimpleDbContext
    {
        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();
            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 IDbRepository<T> where T : class
    {
        //基础方法
        void Add(T entity);
        void Delete(System.Linq.Expressions.Expression<Func<T, bool>> where);
        void Delete(T entity);
        T GetByKey(object id);
        System.Linq.IQueryable<T> Table { get; }
        void Update(T entity);

        //扩展方法(调用就会立即执行)
        int DeleteEx(System.Linq.Expressions.Expression<Func<T, bool>> where);
        int UpdateEx(System.Linq.Expressions.Expression<Func<T, bool>> filterExpression, System.Linq.Expressions.Expression<Func<T, T>> updateExpression);
        int UpdateEx(System.Linq.Expressions.Expression<Func<T, T>> updateExpression);
    }
public class DbRepository<T> : IDbRepository<T> where T : class
    {
        private SimpleDbContext _DataContext;

        private IDbSet<T> TModel;

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

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

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

        #region 基础方法

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

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

        public virtual void Update(T entity)
        {
            TModel.Attach(entity);
            _DataContext.Entry(entity).State = EntityState.Modified;
        }

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

        public virtual void Delete(Expression<Func<T, bool>> where)
        {
            IEnumerable<T> objects = TModel.Where<T>(where).AsEnumerable();
            foreach (T 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<T, T>> updateExpression)
        {
            return TModel.Update<T>(updateExpression);
        }

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

        public int DeleteEx(Expression<Func<T, bool>> where)
        {
            return TModel.Delete(where);
        }
        #endregion
    }
  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(ISimpleDbContext context)
        {
            _simpleDbContext = context as 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;
        }
    }
时间: 2024-10-17 21:28:01

EntityFreamWork6.0 数据库底层访问封装的相关文章

C# .NET更智能的数据库操作的封装完整版(重构)

前述: 第一次发表文章,不过是对数据库简单的封装,主要是阐述下思路.那么在上篇文章,在大家的指导下和提出意见,并自己对代码进行了思考.在这两天我重构了新的框架,我觉得我写的可以称得上框架,为什么?请大家往下看.不过在项目中没有很多注释.笔者除了课余学习时候,大部分时间在完成学校的功课,没有许多时间,所以也就偷下懒,请大家体谅. 这次框架分为几个部分:拼接数据库语句.数据库执行.数据库连接控制.异常类.用户使用的DbHelper.等下我回用文字和图还分析这个部分.经过重构后,类增多了,而且能够极大

Java进阶(二十五)Java连接mysql数据库(底层实现)

Java进阶(二十五)Java连接mysql数据库(底层实现) 前言 很长时间没有系统的使用java做项目了.现在需要使用java完成一个实验,其中涉及到java连接数据库.让自己来写,记忆中已无从搜索.特将之前使用的方法做一简单的总结.也能够在底层理解一下连接数据库的具体步骤. 实现 首先需要导入相关的jar包,我使用的为:mysql-connector-java-5.1.7-bin.jar. 下面来看一下我所使用的数据库连接方法类: MysqlUtil.java package cn.edu

C# .NET更智能的数据库操作的封装

前述: 对数据库操作的封装,相信网络上已经有一大堆,ORM框架,或者是.NET本身的EF,都很好的支持数据库操作.这篇文章是分享自己所思考的,对数据库操作的简单封装.我对于这篇文章,认为被浏览者所关注重点的是怎么分析设计数据库操作封装,代码是其次.而且,这是我第一篇文章,为了想好怎么实现花了些天,代码是博客发表时现写的.所以我想,使用可能还有bug,而且没有try catch异常的设计. 这个框架我理应做到对数据库无关,无论是哪个数据库都能够使用.不过,重点在于分析,而不是代码.所以,为了更好的

Entity Framework底层操作封装V2版本(1)

因为同志们一直给我提建议说,以前发的版本有问题.所以经过了我这一年多的使用和扩展,现在方法基本稳定了.现在贴出来给大家使用: 首先上场的是数据库操作层: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Linq.Expressions; using System.Data.Objects.DataClasses; using System.Refl

Entity Framework底层操作封装V2版本(2)

这个类是真正的数据库操作类,上面的那个类只是调用了这个封装类的方法进行的操作 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Linq.Expressions; using System.Data.Entity; using System.Data.Linq; using System.Data.Objects; using System.Refl

PHP中对数据库操作的封装

在动态网面设计中很多都要涉及到对数据库的操作,但是有时跟据需要而改用其它后台数据库,就需要大量修改程序.这是一件枯燥.费时而且容易出错的功作.其实我们可以用PHP中的类来实现对数据库操作的封装,从而使写出的程序在很小的改动下就可以完成后台数据库的更改. <? class dbInterface{ var $dbID=1; //用于确定当前操作的数据库,当dbID为1代表MySql,当为 2代表 SQL Server,为3时为ODBC或其它. var $dbHost; //数据库所在主机域名 va

数据库无法访问,用户 NT AUTHORITY/SYSTEM或NT AUTHORITY\NETWORK SERVICE登录失败的解决办法

问题:win7中的在IIS 7.0中,在 Default Web Site 目录下挂一虚拟目录. 在相应的应用程序池 DefaultAppPool 设置标识设置成NetworkService. 但是打开页面后,无法打开登录所请求的数据库,用户登录NT AUTHORITY\NETWORK SERVICE失败. 解决办法: 1.打开sqlserver Management studio,在安全性-登录名 下新建一个登记名NETWORK SERVICE ,设置默认数据库为要访问的数据库. 2.然后选

2014-07-30 MVC框架中对SQL Server数据库的访问

今天是在吾索实习的第16天.我自己主要学习了基于MVC框架的系统的开发时,对SQL Server数据库的相关访问.其步骤如下: 第一步,在Models文件夹中创建一个类,并命名为Movies.cs,如图1所示: 图1 第二步,在上述Movies.cs文件中的namespace MvcTest.Models{}中输入如下代码: 1 public class Movie 2 { 3 public int ID { get; set; } 4 public string Title { get; se

Entity Framework底层操作封装V2版本(5)

这个框架到现在最大的变化马上就要出现了,哪就是对缓存的使用.因为系统经常要去读取数据库数据,但是大家知道,数据库的处理能力是有限的,所以对于一些数据量不大,但是又 需要经常去读取的功能来说,更好的方法就是使用缓存. 上面4的方法是不适用缓存的 using System; using System.Collections.Generic; using System.Linq; using System.Text; using JFrame.AccessCommon; using System.Da