分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

学习总结:搭建自己的框架WedeNet(二)

发布时间:2023-09-06 01:27责任编辑:董明明关键词:暂无标签

 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-基础设施层已经构建好了。

学习总结:搭建自己的框架WedeNet(二)

原文地址:https://www.cnblogs.com/zhaow/p/9399434.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved