Entity Framework 第八篇 结构优化

在之前的文章里,业务层直接调用一个包装的仓储类入口,忽略了DAL层,在业务层绕过DAL直接调用仓储类似乎也没什么大的问题,但是这样做有一个很大的弊端,就是无法做到DAL层的原子操作的复用。假如多个业务对象调用一个原子操作,每次都要通过仓储类重写,造成了代码的冗余,因此DAL层还是需要的,另外就是业务层可以采用UnitOfWork的思想去扩展,这样业务层可以共用一个数据上下文,从而保证了事务。

所以大致优化了架构。

仓储类改成泛型的结构

 public class BaseRepository<TEntity> : IRepository, IDisposable where TEntity : class
    {
        private MyDbContext dbContext;

        public MyDbContext DbContext
        {
            get
            {
                return dbContext;
            }
            set
            {
                dbContext = value;
            }
        }

        private bool disposed;

        public BaseRepository()
        { }

        public BaseRepository(MyDbContext _dbContext)
        {
            this.dbContext = _dbContext;

        }

        #region 增删改查

        /// <summary>
        /// 新增实体对象
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public int Insert(TEntity model)
        {
            return this.ChangeObjectState(model, EntityState.Added);
        }

        /// <summary>
        /// 新增实体对象集合
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="models"></param>
        /// <returns></returns>
        public int Insert(IEnumerable<TEntity> models)
        {
            return this.ChangeObjectState(models, EntityState.Added);
        }

        /// <summary>
        /// 持久化对象更改
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public int Update(TEntity model)
        {
            return this.ChangeObjectState(model, EntityState.Modified);
        }

        /// <summary>
        /// 更新对象集合
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="models"></param>
        /// <returns></returns>
        public int Update(IEnumerable<TEntity> models)
        {
            return this.ChangeObjectState(models, EntityState.Modified);
        }

        /// <summary>
        /// 更新对象部分属性
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="predicate"></param>
        /// <param name="updateAction"></param>
        /// <returns></returns>
        public int Update(Expression<Func<TEntity, bool>> predicate, Action<TEntity> updateAction)
        {
            if (predicate == null)
                throw new ArgumentNullException("predicate");
            if (updateAction == null)
                throw new ArgumentNullException("updateAction");

            //dbContext.Configuration.AutoDetectChangesEnabled = true;
            var _model = dbContext.Set<TEntity>().Where(predicate).ToList();
            if (_model == null) return 0;
            _model.ForEach(p =>
            {
                updateAction(p);
                dbContext.Entry<TEntity>(p).State = EntityState.Modified;
            });
            return Save();
        }

        /// <summary>
        /// 删除实体对象
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public int Delete(TEntity model)
        {
            return this.ChangeObjectState(model, EntityState.Deleted);
        }

        /// <summary>
        /// 删除实体对象集合
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="models"></param>
        /// <returns></returns>
        public int Delete(IEnumerable<TEntity> models)
        {
            return this.ChangeObjectState(models, EntityState.Deleted);
        }

        /// <summary>
        /// 删除实体对象集合(符合部分条件的)
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public int Delete(Expression<Func<TEntity, bool>> predicate)
        {
            List<TEntity> _list = null;

            _list = dbContext.Set<TEntity>().Where(predicate).ToList();
            foreach (var item in _list)
            {
                dbContext.Entry<TEntity>(item).State = EntityState.Deleted;
            }
            return Save();
        }

        public IList<TEntity> Search(Expression<Func<TEntity, bool>> predicate = null)
        {
            if (predicate == null)
            {
                return dbContext.Set<TEntity>().ToList();
            }
            else
            {
                return dbContext.Set<TEntity>().Where(predicate).ToList();
            }

        }

        /// <summary>
        /// 查询单个记录
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public TEntity SearchFirstOrDefault(Expression<Func<TEntity, bool>> predicate = null)
        {
            if (predicate == null)
            {
                return dbContext.Set<TEntity>().FirstOrDefault();
            }
            else
            {
                return dbContext.Set<TEntity>().Where(predicate).FirstOrDefault();
            }

        }

        /// <summary>
        /// 查询多笔记录
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public IList<TEntity> SearchList(Expression<Func<TEntity, bool>> predicate = null)
        {

            if (predicate == null)
            {
                return dbContext.Set<TEntity>().ToList();
            }
            else
            {
                return dbContext.Set<TEntity>().Where(predicate).ToList();
            }
        }

        public IList<TEntity> GetPaged(out int total, Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, int index = 1, int size = 20)
        {
            int skipCount = (index - 1) * size;
            var query = Get(filter, orderBy);
            total = query.Count();
            query = skipCount > 0 ? query.Skip(skipCount).Take(size) : query.Take(size);
            return query.ToList();
        }

        public IList<TEntity> GetPaged(out int total, Expression<Func<TEntity, bool>> filter = null, string orderBy = null, int index = 1, int size = 20)
        {
            int skipCount = (index - 1) * size;
            var query = Get(filter, orderBy);
            total = query.Count();
            query = skipCount > 0 ? query.Skip(skipCount).Take(size) : query.Take(size);
            return query.ToList();
        }

        /// <summary>
        /// 执行带参数的sql语句,返回List
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="strsql"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        public IEnumerable<TEntity> GetList(string strsql, SqlParameter[] paras)
        {
            return dbContext.Database.SqlQuery<TEntity>(strsql, paras).ToList();
        }

        /// <summary>
        /// 执行不带参数的sql语句,返回list
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="strsql"></param>
        /// <returns></returns>
        public IEnumerable<TEntity> GetList(string strsql)
        {
            return dbContext.Database.SqlQuery<TEntity>(strsql).ToList();
        }

        /// <summary>
        ///  执行带参数的sql语句,返回一个对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="strsql"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        public TEntity GetOneEntity(string strsql, SqlParameter[] paras)
        {
            return dbContext.Database.SqlQuery<TEntity>(strsql, paras).Cast<TEntity>().First();
        }

        /// <summary>
        ///  执行不带参数的sql语句,返回一个对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="strsql"></param>
        /// <returns></returns>
        public TEntity GetOneEntity(string strsql)
        {
            return dbContext.Database.SqlQuery<TEntity>(strsql).Cast<TEntity>().First();
        }

        /// <summary>
        /// 执行带参数的sql语句,返回List
        /// </summary>
        /// <typeparam name="TView"></typeparam>
        /// <param name="strsql"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        public IEnumerable<TView> GetList<TView>(string strsql, SqlParameter[] paras)
        {
            return dbContext.Database.SqlQuery<TView>(strsql, paras).ToList();
        }

        /// <summary>
        /// 执行不带参数的sql语句,返回list
        /// </summary>
        /// <typeparam name="TView"></typeparam>
        /// <param name="strsql"></param>
        /// <returns></returns>
        public IEnumerable<TView> GetList<TView>(string strsql)
        {
            return dbContext.Database.SqlQuery<TView>(strsql).ToList();
        }

        /// <summary>
        ///  执行带参数的sql语句,返回一个对象
        /// </summary>
        /// <typeparam name="TView"></typeparam>
        /// <param name="strsql"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        public TView GetOneEntity<TView>(string strsql, SqlParameter[] paras)
        {
            return dbContext.Database.SqlQuery<TView>(strsql, paras).Cast<TView>().First();
        }

        /// <summary>
        ///  执行不带参数的sql语句,返回一个对象
        /// </summary>
        /// <typeparam name="TView"></typeparam>
        /// <param name="strsql"></param>
        /// <returns></returns>
        public TView GetOneEntity<TView>(string strsql)
        {
            return dbContext.Database.SqlQuery<TView>(strsql).Cast<TView>().First();
        }

        /// <summary>
        /// 获取查询数量
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        public int GetCount(string sql, SqlParameter[] paras)
        {
            return dbContext.Database.SqlQuery(typeof(int), sql, paras).Cast<int>().First();
        }

        #endregion

        #region 私有方法

        private int Save()
        {
            int effect = 0;
            if (!this.dbContext.IsTransaction)
            {
                effect = this.dbContext.SaveChanges();
            }
            return effect;
        }

        /// <summary>
        /// 变更上下文管理器(对象)
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="model"></param>
        /// <param name="state"></param>
        private int ChangeObjectState(TEntity model, EntityState state)
        {
            //_context.Configuration.ValidateOnSaveEnabled = false;
            dbContext.Entry<TEntity>(model).State = state;
            return Save();

        }

        /// <summary>
        /// 变更上下文管理器(对象集合)
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="model"></param>
        /// <param name="state"></param>
        private int ChangeObjectState(IEnumerable<TEntity> model, EntityState state)
        {
            if (model == null) return 0;

            //_context.Configuration.AutoDetectChangesEnabled = false;
            model.ToList().ForEach(p => dbContext.Entry<TEntity>(p).State = state);
            return Save();

        }

        public IQueryable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, string orderBy = null)
        {
            IQueryable<TEntity> query = dbContext.Set<TEntity>();
            if (filter != null)
            {
                query = query.Where(filter);
            }
            if (!string.IsNullOrEmpty(orderBy))
            {
                query = query.OrderBy(orderBy);
            }
            return query.AsQueryable();
        }

        public IQueryable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null)
        {
            IQueryable<TEntity> query = dbContext.Set<TEntity>();
            if (filter != null)
            {
                query = query.Where(filter);
            }
            if (orderBy != null)
            {
                orderBy(query).AsQueryable();
            }
            return query.AsQueryable();
        }

        #endregion

        public int ExecuteSqlCommand(string sql, params SqlParameter[] paras)
        {
            if (this.dbContext.IsTransaction)
            {
                if (dbContext.Database.CurrentTransaction == null)
                {
                    dbContext.Database.BeginTransaction();
                }
            }
            return dbContext.Database.ExecuteSqlCommand(sql, paras);
        }

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

        public virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    this.dbContext.Dispose();
                }
            }
            this.disposed = true;
        }
    }

DAL 单元类继承泛型类

 public class UserRepository : BaseRepository<S_Users>
    {

        public bool DelUserRoles(string id)
        {

业务层 继承基类 保证可以共用一个数据上下文

 public class BaseBiz
    {
        protected MyDbContext DbContext = null;

        public BaseBiz()
        {
            DbContext = DbContextFactory.GetCurrentDbContext<XFDbContext>();

        }
    
 public class DbContextFactory
    {

        public static T GetCurrentDbContext<T>() where T : DbContext, new()
        {
            string name = typeof(T).Name;
            T dbContext = CallContext.GetData(name) as T;
            if (dbContext == null)
            {
                dbContext = new T();
                CallContext.SetData(name, dbContext);
            }
            return dbContext;
        }

具体的业务类

 public class S_Users_Cls:BaseBiz
    {
        protected UserRepository UserRepository = null;

        public S_Users_Cls()
        {
            UserRepository = RepositoryFactory.CreateRepository<UserRepository>(this.DbContext);
        }

仓储工厂类  将DAL单元仓储类 缓存起来 避免每次都要去构造

public class RepositoryFactory
    {
        private static Dictionary<Type, IRepository> Repositorys = new Dictionary<Type, IRepository>();

        private static object locker = new object();

        public static void Clear()
        {
            lock (locker)
            {
                Repositorys.Clear();
            }
        }

        public static bool Exists(Type key)
        {
            //T local;
            IRepository local;
            if (key == null)
            {
                return false;
            }
            return Repositorys.TryGetValue(key, out local);
        }

        public static IRepository Get(Type key)
        {
            IRepository local = null;
            if (key == null)
            {
                return null;
            }
            Repositorys.TryGetValue(key, out local);
            return local;
        }

        public static void Insert(Type key, IRepository value)
        {
            if ((key != null) && (value != null))
            {
                lock (locker)
                {
                    Repositorys[key] = value;
                }
            }
        }

        public static void Remove(Type key)
        {
            if (key != null)
            {
                lock (locker)
                {
                    Repositorys.Remove(key);
                }
            }
        }

        public static T CreateRepository<T>(MyDbContext myDbContext) where T : class,IRepository, new()
        {
            Type key=typeof(T);
            T repository = default(T);
            if (Exists(key) && Get(key) != null)
            {
                 repository = (T)Get(key);
            }
            else
            {
                 repository = new T();
                 Insert(key,repository);
            }
            repository.DbContext = myDbContext;
            return (T)repository;
        }
    }

将事务包装在DbContext里

 public class MyDbContext : DbContext, ITransaction
    {
       public MyDbContext(string connectionString)
            : base(connectionString)
        {
            // 是否启动延迟加载
            Configuration.LazyLoadingEnabled = false;
            // 是否启动代理
            Configuration.ProxyCreationEnabled = false;
            Configuration.AutoDetectChangesEnabled = false;
            Configuration.ValidateOnSaveEnabled = false;
        }

        public void BeginTransaction()
        {
            this.IsTransaction = true;
        }

        public int Commit()
        {
            int reault = this.SaveChanges();
            this.IsTransaction = false;
            DbContextTransaction transaction = this.Database.CurrentTransaction;
            if (transaction != null)
            {
                transaction.Commit();
                transaction.Dispose();
                reault += 1;
            }
            return reault;
        }

        public void Rollback()
        {
            this.IsTransaction = false;
            DbContextTransaction transaction = this.Database.CurrentTransaction;
            if (transaction != null)
            {
                transaction.Rollback();
                transaction.Dispose();
            }
        }

        private bool isTransaction = false;

        public bool IsTransaction
        {
            get { return isTransaction; }
            set { this.isTransaction = value; }
        }

    }
public class XFDbContext : MyDbContext
    {
        public XFDbContext()
            : base("XFJD")
        {
            // 防止Entity变更导致数据库自动更新
            Database.SetInitializer<XFDbContext>(null);
        }

最后看看业务层如何事务调用

   public bool Add(S_Users model)
        {

            bool result = false;
            this.DbContext.BeginTransaction();
            try
            {
                this.UserRepository.Insert(model);

int effect = this.DbContext.Commit();
                result = effect > 0;
            }
            catch (Exception ex)
            {
                this.DbContext.Rollback();
            }
            return result;
        }

非事务性操作

  public bool EditPwd(S_Users model)
        {
            return UserRepository.EditPwd(model);
        }

最后,结构优化用了时间比较短,不敢保证代码是否会存在一些问题。

时间: 2024-10-11 10:19:42

Entity Framework 第八篇 结构优化的相关文章

Entity Framework学习中级篇

1-EF支持复杂类型的实现 本节,将介绍如何手动构造复杂类型(ComplexType)以及复杂类型的简单操作. 通常,复杂类型是指那些由几个简单的类型组合而成的类型.比如:一张Customer表,其中有FristName和LastName字段,那么对应的Customer实体类将会有FristName和LastName这两个属性.当我们想把FirstName和LastName合成一个名为CustomerName属性时,此时,如果要在EF中实现这个目的,那么我们就需要用到复杂类型. 目前,由于EF不

Entity Framework 4 第一篇 POCO

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 Entity Framework 4 第一篇 POCO 在EFv1版本中,并没有提供对POCO(Plain Old CLR Objects)的支持.目前,在.Net4.0 Beta2中的EF 4完善了很多.可以预见,正式的EF4版本应该会有很多

entity framework 新手入门篇(1)-建立模型

entity framework是微软官方免费提供给大家的一套ORM(Object Relational Mapping对象关系映射)解决方案.它不仅可以帮助我们解决数据缓存的问题,还能在最小的开销下实现完全的OO(Object Oriented面向对象)编程.实乃中小项目中敏捷开发的一大福祉.博主作为一只刚入本行的菜鸟,有幸参加开发了几个使用entity framework(以下简称EF)的项目,虽然在这些项目开发的过程中,走了许多的弯路,网上的资料也不甚齐全.在摸爬滚打了一年之后,也算有了一

Entity Framework 6 预热、启动优化

虽然文章题目是针对EF的,但涉及的内容不仅仅是EF. 场景介绍 目前在做的一个项目,行业门户,项目部分站点按域名划分如下: user.xxx.com:用户登陆注册 owner.xxx.com:个人用户后台 company.xxx.com:企业后台 manage.xxx.com:网站管理 其中user.xxx.com为个人用户及企业用户登陆入口,manage.xxx.com/login为网站管理后台登陆入口. 四个项目都是mvc4+ef6+autofac+automapper. 补充信息: .ne

Entity Framework学习初级篇

1--EF基本概况 最近在学习研究微软的EF,通过这时间的学习研究,感觉这个EF目前来说还不是很完善,半成品.不过,据说在.Net4.0中,微软将推荐使用此框架,并会有所改善.而且,现在基本上所有数据库均提供了对EF的支持.因此,为以后做技术准备可以学习研究以下.但是,我个人觉得就目前来说,在实际项目慎用此框架. 下面简单的介绍以下这个EF. 在.Net Framework SP1微软包含一个实体框架(Entity Framework),此框架可以理解成微软的一个ORM产品.用于支持开发人员通过

entity framework 新手入门篇(3)-entity framework实现orderby,count,groupby,like,in,分页等

前面我们已经学习了entityframework的基本的增删改查,今天,我们将在EF中实现一些更加贴近于实际功能的SQL方法. 承接上面的部分,我们有一个叫做House的数据库,其中包含house表和seller表. 在本次学习之前,我们先要了解一个神奇的接口,iqueryable这个接口类似于ienumable,但并不完全相同,Iqueryable是可查询类型需要实现的最重要的接口,在其Count,ToList,ToArray之后才会真正执行查询,所以,为了保证性能,请尽量在最后一步在进行Co

entity framework 新手入门篇(2)-entity framework基本的增删改查

经过前两节的简单描述,终于可以进入entity framework的使用部分了.本节将对entity framework原生的增删改查进行讲解. 承接上面的部分,我们有一个叫做House的数据库,其中包含house表和seller表. 一.entity framework 相关类的理解. 首先,House数据库在映射后会生成一个名为HouseEntities的类,这个类我们称之为数据上下文,可以简单的理解为数据库的部分映射(如果映射了全部的表,视图,存储过程,则可看作全部映射). 使用数据库的时

Entity Framework基础—第二篇

实体框架(Entity Framework) 简称EF,属于数据持久(持久保存)架里面的一种,其他的还有NHibernate,ibaties,Dapper.PetaPOCO...等,都是基于ORM思想. 首先介绍下O/R Mapping(ORM) 1.什么是ORM?ORM指的是面向对象的对象模型和关系数据库的数据结构之间的相互转化,可以理解为把表实体和表相互转化(在任何平台都适用,如php,java等). 传统ADO.net操作数据库: 基于ORM思想操作数据库: 接下来我们就一步步创建项目:

Entity Framework 第三篇 实体特性声明

Entity Framework中对实体的特性声明有着严格的要求 1.实体必须要有主键特性,但是如果实体没有主键特性那怎么办? public int ExecuteSqlCommand(string sql, params SqlParameter[] paras) { if (this.IsTransaction) { if (dbContext.Database.CurrentTransaction == null) { dbContext.Database.BeginTransaction