zoukankan      html  css  js  c++  java
  • 搭建自己的框架WedeNet(二)

     WedeNet2018.Infrastructure-基础设施层:
    结构如下:

    Tools结构如下:

    考虑到系统可能会有多个数据上下文(暂时以两个为例),所以根据需要定义两个T4模板用来生成对应的entities和dbcontext类,每个T4模板对应一个数据库连接,这些数据库连接配置在应用层的配置文件中(如UI层web.config或者WCF寄宿层的app.config)。

    生成的结果如下:

    在此,我把UnitOfWork和Repository都看做为组件,和它们所依赖的dbcontext都统一放在了Components目录下。
    仓储需要包装不同的EF entitiy,自然需要定义为泛型接口,如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace WedeNet2018.Infrastructure.Components
    {
        public interface IRepository<T> 
            where T : class
        {
            IQueryable<T> All();
            IQueryable<T> Filter(Expression<Func<T, bool>> predicate);
            T Find(params object[] keys);
            T Find(Expression<Func<T, bool>> predicate);
            void Insert(T t);
            void Insert(IEnumerable<T> entities);
            void Delete(T t);
            void Delete(IEnumerable<T> entities);
            void Update(T t);
            void Update(IEnumerable<T> entities);
            void Clear();
        }
    }
    

    接口的实现如下:

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Entity;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace WedeNet2018.Infrastructure.Components
    {
        public class EntityRepository<TContext,TEntity> : IRepository<TEntity>
            where TContext : DbContext
            where TEntity : class
        {
            protected TContext context;
            protected DbSet<TEntity> dbSet;
    
            public EntityRepository(TContext dbContext)
            {
                context = dbContext;
                dbSet = context.Set<TEntity>();
            }
    
            protected virtual TContext Context { get { return context; } }
            protected virtual DbSet<TEntity> DbSet { get { return dbSet; } }
            /// <summary>
            /// 查询全部当前实体数据集
            /// </summary>
            /// <returns>IQueryable集合</returns>
            public virtual IQueryable<TEntity> All()
            {
                return DbSet.AsQueryable();
            }
            /// <summary>
            /// 条件查询当前实体数据集
            /// </summary>
            /// <param name="predicate">查询条件</param>
            /// <returns>IQueryable集合</returns>
            public virtual IQueryable<TEntity> Filter(Expression<Func<TEntity, bool>> predicate)
            {
                return DbSet.Where(predicate).AsQueryable<TEntity>();
            }
    
            /// <summary>
            /// 查找指定主键的数据
            /// </summary>
            /// <param name="keys">指定主键</param>
            /// <returns>符合编号的记录,不存在返回null </returns>
            public virtual TEntity Find(params object[] keys)
            {
                return DbSet.Find(keys);
               
            }
    
            /// <summary>
            /// 查找指定条件的单条数据
            /// </summary>
            /// <param name="predicate">查询条件</param>
            /// <returns>返回符合条件的数据,或者null</returns>
            public virtual TEntity Find(Expression<Func<TEntity, bool>> predicate)
            {
                return DbSet.FirstOrDefault(predicate);
            }
            /// <summary>
            /// 上下文中插入单个实体
            /// </summary>
            /// <param name="entity"></param>
            public virtual void Insert(TEntity entity)
            {
                if (Context.Entry(entity).State == EntityState.Detached)
                {
                    Context.Entry(entity).State = EntityState.Added;
                    //DbSet.Add(entity);
                }
            }
            /// <summary>
            /// 上下文中批量插入实体
            /// </summary>
            /// <param name="entities"></param>
            public virtual void Insert(IEnumerable<TEntity> entities)
            {
                try
                {
                    Context.Configuration.AutoDetectChangesEnabled = false;
                    foreach (TEntity entity in entities)
                    {
                        Insert(entity);
                    }
                }
                finally
                {
                    Context.Configuration.AutoDetectChangesEnabled = true;
                }
            }
    
            /// <summary>
            /// 上下文中删除单个实体
            /// </summary>
            /// <param name="entity"></param>
            public virtual void Delete(TEntity entity)
            {
                if (Context.Entry(entity).State == EntityState.Detached)
                {
                    DbSet.Attach(entity);
                }
                DbSet.Remove(entity);
            }
            /// <summary>
            /// 上下文中批量删除实体
            /// </summary>
            /// <param name="entities"></param>
            public virtual void Delete(IEnumerable<TEntity> entities)
            {
                try
                {
                    Context.Configuration.AutoDetectChangesEnabled = false;
                    foreach (TEntity entity in entities)
                    {
                        Delete(entity);
                    }
                }
                finally
                {
                    Context.Configuration.AutoDetectChangesEnabled = true;
                }
            }
            /// <summary>
            /// 上下文中更新单个实体
            /// </summary>
            /// <param name="entity"></param>
            public virtual void Update(TEntity entity)
            {
                if (Context.Entry(entity).State == EntityState.Detached)
                {
                    DbSet.Attach(entity);
                }
                Context.Entry(entity).State = EntityState.Modified;
            }
            /// <summary>
            /// 上下文中批量更新实体
            /// </summary>
            /// <param name="entities"></param>
            public virtual void Update(IEnumerable<TEntity> entities)
            {
                try
                {
                    Context.Configuration.AutoDetectChangesEnabled = false;
                    foreach (TEntity entity in entities)
                    {
                        Update(entity);
                    }
                }
                finally
                {
                    Context.Configuration.AutoDetectChangesEnabled = true;
                }
            }
    
            public virtual void Clear()
            {
    
            }
        }
    }
    

    在这个仓储基类里,引入了该仓储依赖的dbcontext,这个dbcontext会在系统初始化该仓储的时候传入,并且是单例的。这样才能保证UnitOfWork操作的一致性。
    另外,针对不同的dbcontext,我也定义了对应的抽象类,如:

    目的是在做IOC的时候一个具体类型必须对应一个基类,而在这两个抽象类内部都继承了DbContext,如:

    // <auto-generated>
    //     此代码由工具生成。
    //     对此文件的更改可能会导致不正确的行为,并且如果
    //     重新生成代码,这些更改将会丢失。
    //	   如存在本生成代码外的新需求,请在相同命名空间下创建同名分部类进行实现。
    // </auto-generated>
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Data.Entity;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.ComponentModel.DataAnnotations;
    
    namespace WedeNet2018.Infrastructure
    {
    	public abstract class AbsWedeDBContex:DbContext
    	{
    		//连接字符串名称:基于Config文件中连接字符串的配置
    		const string connectionStringName = "constring";
    
    		public AbsWedeDBContex()
    			: base(connectionStringName)
    		{ 
    			
    		}
    	}
    }
    

    接下来就是UnitOfWork,接口定义如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace WedeNet2018.Infrastructure.Components
    {
        /// <summary>
        /// 定义工作单元统一接口
        /// </summary>
        public interface IUnitOfWorks
        {
            IQueryable<T> Where<T>(Expression<Func<T, bool>> predicate) where T : class;
            IQueryable<T> All<T>() where T : class;
    
            T Find<T>(object id) where T : class;
            T Find<T>(Expression<Func<T, bool>> predicate) where T : class;
    
            void Add<T>(T t) where T : class;
            void Add<T>(IEnumerable<T> items) where T : class;
    
            void Update<T>(T t) where T : class;
            void Update<T>(IEnumerable<T> items) where T : class;
    
            void Delete<T>(T t) where T : class;
            void Delete<T>(IEnumerable<T> items) where T : class;
    
            void Clear<T>() where T : class;
            bool IsCommitted { get; }
    
            int Commit();
        }
    }
    

    和上面定义了两个dbcontext抽象基类一样,出于IOC考虑,这里也定义了两个实现了IUnitOfWorks接口的接口,如:

    下面是对应的实现类,如:

    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using System.Threading.Tasks;
    using WedeNet2018.Common;
    
    namespace WedeNet2018.Infrastructure.Components
    {
        /// <summary>
        /// 实现一个工作单元,将使用NInject注册为单例
        /// </summary>
        /// <typeparam name="TDBContext">该工作单元使用的数据上下文类型</typeparam>
        public class XF0816UnitOfWorks<TDBContext> : IXF0816UnitOfWorks, IDisposable
            where TDBContext : DbContext
        {
            protected TDBContext dbContext;
    
            public XF0816UnitOfWorks(TDBContext context)
            {
                dbContext = context;
            }
    
            //构造通用的Repository
            private IDictionary<Type, object> repositoryTable = new Dictionary<Type, object>();
    
            //注册其它的Repository
            public void Register<T>(IRepository<T> repository) where T : class
            {
                var key = typeof(T);
                if (!repositoryTable.ContainsKey(key))
                    repositoryTable.Add(key, repository);
            }
    
    
            private IRepository<T> GetRepository<T>()
                where T : class
            {
                IRepository<T> repository = null;
                var key = typeof(T);
    
                if (repositoryTable.ContainsKey(key))
                    repository = (IRepository<T>)repositoryTable[key];
                else
                {
                    repository = GenericRepository<T>();
                    repositoryTable.Add(key, repository);
                }
    
                return repository;
            }
    
            protected virtual IRepository<T> GenericRepository<T>() where T : class
            {
                return new EntityRepository<TDBContext, T>(dbContext);
            }
            /// <summary>
            /// 条件查询当前实体数据集
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="predicate">查询条件</param>
            /// <returns>IQueryable集合</returns>
            public System.Linq.IQueryable<T> Where<T>(Expression<Func<T, bool>> predicate)
               where T : class
            {
                return GetRepository<T>().Filter(predicate);
            }
            /// <summary>
            /// 查询全部当前实体数据集
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <returns>IQueryable集合</returns>
            public System.Linq.IQueryable<T> All<T>() where T : class
            {
                return GetRepository<T>().All();
            }
    
            /// <summary>
            /// 查找指定主键的数据
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="id">实体主键</param>
            /// <returns>符合编号的记录,不存在返回null</returns>
            public T Find<T>(object id) where T : class
            {
                return GetRepository<T>().Find(id);
            }
            /// <summary>
            /// 查找指定条件的单条数据
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="predicate">查询条件</param>
            /// <returns>返回符合条件的数据,或者null</returns>
            public T Find<T>(Expression<Func<T, bool>> predicate) where T : class
            {
                return GetRepository<T>().Find(predicate);
            }
            /// <summary>
            /// 上下文中插入单个实体
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="t">实体</param>
            public void Add<T>(T t) where T : class
            {
                GetRepository<T>().Insert(t);
            }
            /// <summary>
            /// 上下文中批量插入实体
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="items">实体集合</param>
            public void Add<T>(IEnumerable<T> items) where T : class
            {
                GetRepository<T>().Insert(items);
            }
            /// <summary>
            /// 上下文中更新单个实体
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="t">实体</param>
            public void Update<T>(T t) where T : class
            {
                GetRepository<T>().Update(t);
            }
            /// <summary>
            /// 上下文中批量更新实体
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="items">实体集合</param>
            public void Update<T>(IEnumerable<T> items) where T : class
            {
                GetRepository<T>().Update(items);
            }
            /// <summary>
            /// 上下文中删除单个实体
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="t">实体</param>
            public void Delete<T>(T t) where T : class
            {
                GetRepository<T>().Delete(t);
            }
            /// <summary>
            /// 上下文中批量删除实体
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="items">实体集合</param>
            public void Delete<T>(IEnumerable<T> items) where T : class
            {
                GetRepository<T>().Delete(items);
            }
    
            public void Clear<T>() where T : class
            {
                GetRepository<T>().Clear();
            }
    
            /// <summary>
            /// 当前单元操作是否已被提交
            /// </summary>
            public bool IsCommitted { get; private set; }
    
            /// <summary>
            /// 提交当前工作单元
            /// </summary>
            /// <returns></returns>
            public int Commit()
            {
                try
                {
                    int result = dbContext.SaveChanges();
                    return result;
                }
                catch (DbUpdateException e)
                {
                    if (e.InnerException != null && e.InnerException.InnerException is SqlException)
                    {
                        SqlException sqlEx = e.InnerException.InnerException as SqlException;
                        string msg = SqlDataHelper.GetSqlExceptionMessage(sqlEx.Number);
                        throw PublicHelper.ThrowDataAccessException("提交数据更新时发生异常:" + msg, sqlEx);
                    }
                    throw;
                }
            }
    
    
            public void Dispose()
            {
                if (dbContext != null)
                {
                    dbContext.Dispose();
                }
                GC.SuppressFinalize(this);
            }
    
    
        }
    }
    

    到此为止,Infrastructure-基础设施层已经构建好了。

  • 相关阅读:
    Linux启动新进程的几种方法及比较[转]
    部署WEB应用的三种方式[转]
    HTML form label
    其他对象的表单
    Input对象2(貌似是独立标签)
    通过表单展示不一样的页面(input对象)
    神奇的表单
    有效地管理页面布局
    css新奇技术及其未来发展
    进一步讨论页面布局的方法
  • 原文地址:https://www.cnblogs.com/zhaow/p/9399434.html
Copyright © 2011-2022 走看看