标签:批量 ddc uri lse reading 循环 标识 基于接口 基础
现有项目中的orm 并非efcore,而是非主流的npoco,本身没有自带工作单元所以需要自己手撸一个,现记录一下,基于其他orm的工作单元照例实现应该没有什么问题
该实现基于NPOCO,针对其他的ORM实现,所有的实现都基于接口,如需转成其他ORM,只需要将部分实现类重写即可,如UnitOfWorkImpl
实体基类,所有实体继承该类
namespace test.Core
{
///
/// 实体基类
///
public class EntityBase
{
///
/// 唯一标识
///
public long Id { get; set; }
public EntityBase()
{
// Id = GeneratePrimaryKeyIdHelper.GetPrimaryKeyId();
}
}
}
自定义的事务接口实现类
using test.Core;
using NPoco;
using System.Data;
namespace test.DAL
{
internal class DBTransactionImpl : IDBTransaction
{
IDatabase db;
public DBTransaction(IDatabase db)
{
this.db = db;
this.db.BeginTransaction();
}
public virtual void Complete()
{
db.CompleteTransaction();
db = null;
}
public void Dispose()
{
if (db != null)
{
db.AbortTransaction();
}
}
}
}
事务接口
using System;
namespace test.Core
{
public interface IDBTransaction : IDisposable
{
void Complete();
}
}
仓储接口:命令类(提交数据的接口,不包含查询的服务)
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using test.Core;
namespace test.IDAL
{
public interface ICommandBaseRepository
{
#region 新增
///
/// 插入实体
///
Task InsertAsync(T entity) where T : EntityBase;
///
/// 批量插入实体
///
Task InsertBatchAsync(IList entities) where T : EntityBase;
#endregion
#region 更新
///
/// 更新单个实体
///
Task UpdateAsync(T entity) where T : EntityBase;
///
/// 根据实体更新部分字段
///
///
///
///
///
Task UpdateAsync(T entity, Expression> fields) where T : EntityBase;
///
/// 更新实体的部分字段
///
///
///
///
Task UpdateAsync(T entity, IList columns) where T : EntityBase;
///
/// 更新多个实体
///
///
///
Task UpdateBatchAsync(IList entities) where T : EntityBase;
///
/// 根据id集合更新多个记录的某个字段
///
/// 主键值类型 long,int等
/// 字段值类型 long,int等
/// id集合
/// 字段数据,key字段名,value字段值
///
Task UpdateSingleFieldByIdsAsync(IList idList, KeyValuePair column);
///
/// 保存实体,有则更新,无则新增
///
///
///
Task SaveAsync(T entity) where T : EntityBase;
#endregion
#region 删除
///
/// 逻辑删除
///
///
///
Task SoftDeleteAsync(TPrimaryKeyType id);
///
/// 逻辑删除
///
///
///
Task SoftDeleteBatchAsync(IList id);
///
/// 删除记录
///
// Task DeleteAsync(TPrimaryKeyType id);
///
/// 批量删除记录
///
// Task DeleteBatchAsync(IList idList);
#endregion
#region 事务模块
///
/// 开始事务(返回事务对象)
///
///
IDBTransaction BeginDBTransaction();
///
/// 开启事务(不返回事务对象)
///
///
void BeginNewDBTransaction();
///
/// 提交事务事务
///
void CompleteDBTransaction();
///
/// 中断结束事务
///
void AbortDBTransaction();
#endregion
}
}
仓储接口:查询仓储服务
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace test.IDAL
{
public interface IQueryBaseRepository
{
///
/// 获得单条数据
///
///
///
///
Task GetAsync(TPrimaryKeyType id);
///
/// 根据id集合获取多条数据
///
///
///
///
///
Task> GetListByIdsAsync(List ids);
///
/// 根据某个唯一字段列获取单条数据(唯一值)
///
///
///
///
///
Task GetSingleAsync(KeyValuePair column);
///
/// 根据主键是否存在记录
///
Task ExistsAsync(TPrimaryKeyType id);
///
/// 某个字段是否唯一
///
///
///
/// true 唯一 false 不唯一
Task IsUniqueAsync(KeyValuePair column);
}
}
工作单元接口
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using test.Core;
namespace test.IDAL
{
public interface IUnitOfWork
{
///
/// 插入
///
///
///
void RegisterInsert(EntityBase entity, ICommandBaseRepository unitofWorkRepository);
///
/// 保存,不支持多个同一类实体(同一个类型实体只能添加一个,否则会异常)
///
///
///
void RegisterSave(EntityBase entity, ICommandBaseRepository unitofWorkRepository);
///
/// 更新
///
///
///
void RegisterUpdate(EntityBase entity, ICommandBaseRepository unitofWorkRepository);
///
/// 删除
///
///
///
void RegisterDelete(object id, ICommandBaseRepository unitofWorkRepository);
///
/// 根据字段更新
///
///
///
///
void RegisterUpdateByFields(EntityBase entity, IList fields, ICommandBaseRepository unitofWorkRepository);
///
/// 根据id集合更新单个字段
///
///
///
///
void RegisterUpdateSingleFieldByIds(IList id, KeyValuePair column, ICommandBaseRepository unitofWorkRepository);
Task CommitAsync();
}
}
自定义的获取db对象接口,保证一个请求内db是同一个对象即可,可通过依赖注入的addscoped实现
using test.DAL.Repositories;
using System;
using System.Collections.Generic;
using System.Text;
namespace test.DAL
{
internal interface IScopeDBFactory
{
CustomDatabase GetScopeDb();
}
}
IScopeDBFactory 实现类,自行实现即可
using MySql.Data.MySqlClient;
using test.Core;
using NPoco;
using NPoco.FluentMappings;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Reflection;
using System.Text;
namespace test.DAL.Repositories
{
internal class ScopeDBFactoryImpl : IScopeDBFactory
{
protected CustomDatabase Db;
public CustomDatabase GetScopeDb()
{
}
}
}
unitofwork 接口实现
using test.Core;
using test.DAL;
using test.DAL.Repositories;
using test.IDAL;
using NPoco;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
namespace test.DAL
{
internal class UnitOfWorkImpl : IUnitOfWork
{
private Dictionary> addedEntities;
private Dictionary> changedEntities;
private Dictionary> deletedEntities;
private Dictionary saveEntity;
private Dictionary> changedPartFieldEntityList;
private Dictionary> changedPartByIdsEntityList;
private readonly IScopeDBFactory scopeDBFactory;
public UnitOfWorkImpl(IScopeDBFactory scopeDBFactory)
{
addedEntities = new Dictionary>();
changedEntities = new Dictionary>();
deletedEntities = new Dictionary>();
saveEntity = new Dictionary();
changedPartFieldEntityList = new Dictionary>();
changedPartByIdsEntityList = new Dictionary>();
this.scopeDBFactory = scopeDBFactory;
}
public void RegisterInsert(EntityBase entity, ICommandBaseRepository unitofWorkRepository)
{
if (!addedEntities.ContainsKey(unitofWorkRepository))
{
addedEntities.Add(unitofWorkRepository, new List() { entity });
}
else
{
List list = addedEntities[unitofWorkRepository];
if (!list.Contains(entity))
{
addedEntities[unitofWorkRepository].Add(entity);
}
}
}
public void RegisterSave(EntityBase entity, ICommandBaseRepository unitofWorkRepository)
{
if (!saveEntity.ContainsKey(unitofWorkRepository))
{
saveEntity.Add(unitofWorkRepository, entity);
}
else
{
throw new Exception("不能重复添加");
}
}
public void RegisterUpdate(EntityBase entity, ICommandBaseRepository unitofWorkRepository)
{
if (!changedEntities.ContainsKey(unitofWorkRepository))
{
changedEntities.Add(unitofWorkRepository, new List() { entity });
}
else
{
List list = changedEntities[unitofWorkRepository];
if (!list.Contains(entity))
{
changedEntities[unitofWorkRepository].Add(entity);
}
}
}
public void RegisterUpdateByFields(EntityBase entity, IList fields, ICommandBaseRepository unitofWorkRepository)
{
var updatePartModel = new UpdatePartFieldModel();
updatePartModel.Entity = entity;
updatePartModel.Fields = fields;
if (!changedPartFieldEntityList.ContainsKey(unitofWorkRepository))
{
changedPartFieldEntityList.Add(unitofWorkRepository, new List() { updatePartModel });
}
else
{
List list = changedPartFieldEntityList[unitofWorkRepository];
if (!list.Contains(updatePartModel))
{
changedPartFieldEntityList[unitofWorkRepository].Add(updatePartModel);
}
}
}
public void RegisterUpdateSingleFieldByIds(IList idList, KeyValuePair column, ICommandBaseRepository unitofWorkRepository)
{
var updateSingleFieldByIdModel = new UpdateSingleFieldByIdsModel();
updateSingleFieldByIdModel.IdList = idList;
updateSingleFieldByIdModel.Column = column;
if (!changedPartByIdsEntityList.ContainsKey(unitofWorkRepository))
{
changedPartByIdsEntityList.Add(unitofWorkRepository, new List() { updateSingleFieldByIdModel });
}
else
{
List list = changedPartByIdsEntityList[unitofWorkRepository];
if (!list.Contains(updateSingleFieldByIdModel))
{
changedPartByIdsEntityList[unitofWorkRepository].Add(updateSingleFieldByIdModel);
}
}
}
public void RegisterDelete(object id, ICommandBaseRepository unitofWorkRepository)
{
if (!deletedEntities.ContainsKey(unitofWorkRepository))
{
deletedEntities.Add(unitofWorkRepository, new List() { id });
}
else
{
List list = deletedEntities[unitofWorkRepository];
if (!list.Contains(id))
{
deletedEntities[unitofWorkRepository].Add(id);
}
}
}
///
/// 开启事务
///
///
private DBTransaction BeginNewDBTransaction(CustomDatabase db)
{
var scopeTransaction = new DBTransaction(db);
return scopeTransaction;
}
public async Task CommitAsync()
{
//获得db对象 一个请求db是同一个 var db = scopeDBFactory.GetScopeDb();
using (var scope = BeginNewDBTransaction(db))
{
///插入新增的实体
foreach (var repository in this.addedEntities.Keys)
{
var entityList = addedEntities[repository];
if (entityList.Count > 1)
{
await repository.InsertBatchAsync(entityList).ConfigureAwait(false);
}
else
{
await repository.InsertAsync(entityList[0]).ConfigureAwait(false);
}
}
///保存实体 有则更新 无则删除
foreach (var repository in this.saveEntity.Keys)
{
var entity = saveEntity[repository];
await repository.SaveAsync(entity).ConfigureAwait(false);
}
//更新需要修改的实体
foreach (var repository in this.changedEntities.Keys)
{
var entityList = changedEntities[repository];
if (entityList.Count > 1)
{
await repository.UpdateBatchAsync(entityList).ConfigureAwait(false);
}
else
{
await repository.UpdateAsync(entityList[0]).ConfigureAwait(false);
}
}
///更新根据字段更新的实体
foreach (var repository in this.changedPartFieldEntityList.Keys)
{
var updateModelList = changedPartFieldEntityList[repository];
foreach (var updateModel in updateModelList)
{
await repository.UpdateAsync(updateModel.Entity, updateModel.Fields).ConfigureAwait(false);
}
}
///更新根据id集合更新的数据实体
foreach (var repository in this.changedPartByIdsEntityList.Keys)
{
var updateModelList = changedPartByIdsEntityList[repository];
foreach (var updateModel in updateModelList)
{
await repository.UpdateSingleFieldByIdsAsync(updateModel.IdList, updateModel.Column).ConfigureAwait(false);
}
}
///删除实体
foreach (var repository in this.deletedEntities.Keys)
{
var entityList = deletedEntities[repository];
if (entityList.Count > 1)
{
await repository.SoftDeleteBatchAsync(entityList).ConfigureAwait(false);
}
else
{
await repository.SoftDeleteAsync(entityList[0]).ConfigureAwait(false);
}
}
scope.Complete();
addedEntities.Clear();
changedEntities.Clear();
deletedEntities.Clear();
saveEntity.Clear();
changedPartFieldEntityList.Clear();
changedPartByIdsEntityList.Clear();
}
}
}
}
namespace test.DAL
{
internal class UpdatePartFieldModel
{
public EntityBase Entity { get; set; }
public IList Fields { get; set; }
}
internal class UpdateSingleFieldByIdsModel
{
public IList IdList { get; set; }
public KeyValuePair Column { get; set; }
}
}
针对批量删除、批量修改等各种操作,根据各个业务多一层封装UnitOfWork,减少提交工作单元时各种循环,不想要的也可以去掉
以customer业务表为例代码
如下:
namespace test.IDAL
{
public interface ICommandCustomerRepository : ICommandBaseRepository
{
}
}
客户服务仓储单元接口
namespace test.IDAL
{
public interface ICustomerUnitOfWork
{
void RegisterInsert(CustomerEntity entity);
void RegisterInsertBatch(IList entities);
void RegisterUpdate(CustomerEntity entity);
void RegisterUpdateBatch(IList entities);
void RegisterUpdateByFields(CustomerEntity entity,List fields);
void RegisterUpdateSingleFieldByIds(IList idList, KeyValuePair column);
void RegisterDelete(long id);
void RegisterDeleteBatch(IList idList);
Task CommitAsync();
}
}
客户实体
namespace test.Entity
{
///
/// 基础数据-客户信息
///
[MyTableName("Customer")]
[MyPrimaryKey("Id", AutoIncrement = false)]
public class CustomerEntity : EntityBase
{
///
/// 客户名称
///
public string Name { get; set; }
///
/// 客户code
///
///
public string Code { get; set; }
///
/// 是否可用 0 否 1是
///
public bool? IsEnabled { get; set; }
///
/// 邮箱
///
public string Email { get; set; }
///
/// 传真
///
public string Fax { get; set; }
///
/// 联系人
///
public string ContactPerson { get; set; }
///
/// 联系人电话
///
public string ContactTelphone { get; set; }
///
/// 地址
///
public string Address { get; set; }
///
/// 备注
///
public string Remark { get; set; }
}
}
客户服务工作单元实现
namespace test.DAL
{
internal class CustomerUnitOfWorkImpl:ICustomerUnitOfWork , IAutoInject
{
private readonly IUnitOfWork unitOfWork;
private readonly ICommandCustomerRepository commandRepository;
public CustomerUnitOfWorkImpl(ICommandCustomerRepository commandRepository, IUnitOfWork unitOfWork)
{
this.commandRepository = commandRepository;
this.unitOfWork = unitOfWork;
}
public void RegisterInsert(CustomerEntity entity)
{
unitOfWork.RegisterInsert(entity, commandRepository);
}
public void RegisterInsertBatch(IList entities)
{
foreach (var entity in entities)
{
unitOfWork.RegisterInsert(entity, commandRepository);
}
}
public void RegisterUpdate(CustomerEntity entity)
{
unitOfWork.RegisterUpdate(entity, commandRepository);
}
public void RegisterUpdateBatch(IList entities)
{
foreach (var entity in entities)
{
unitOfWork.RegisterUpdate(entity, commandRepository);
}
}
public void RegisterUpdateByFields(CustomerEntity entity, List fields)
{
unitOfWork.RegisterUpdateByFields(entity, fields, commandRepository);
}
public void RegisterUpdateSingleFieldByIds(IList idList, KeyValuePair column)
{
unitOfWork.RegisterUpdateSingleFieldByIds(idList, column, commandRepository);
}
public void RegisterDelete(long entity)
{
unitOfWork.RegisterDelete(entity, commandRepository);
}
public void RegisterDeleteBatch(IList entities)
{
foreach (var entity in entities)
{
unitOfWork.RegisterDelete(entity, commandRepository);
}
}
public async Task CommitAsync()
{
await unitOfWork.CommitAsync().ConfigureAwait(false);
}
}
}
客户服务接口
namespace test.IBLL.Basic
{
public interface ICommandCustomerService
{
///
/// 插入单个实体
///
///
///
Task> InsertAsync(CustomerEntity entity,bool isCommit = true);
///
/// 批量插入实体
///
///
///
Task> InsertBatchAsync(List entityList,bool isCommit = true);
///
/// 根据主键更新实体
///
///
///
Task> UpdateAsync(CustomerEntity entity,bool isCommit = true);
///
/// 更新实体的部分字段
///
///
///
///
Task> UpdateFieldsAsync(CustomerEntity entity, List fields, bool isCommit = true);
///
/// 根据id集合更新某个字段更新
///
///
///
///
///
Task> UpdateSingleFieldByIdsAsync(List idList, KeyValuePair column, bool isCommit = true);
///
/// 根据主键批量更新实体
///
/// 实体集合
///
Task> UpdateBatchAsync(List entityList,bool isCommit = true);
///
/// 根据根据主键删除
///
/// 主键
///
Task> DeleteAsync(long id,bool isCommit = true);
///
/// 批量删除 根据主键
///
/// 主键集合
///
Task> DeleteBatchAsync(IList idList,bool isCommit = true);
///
/// 保存实体,有则更新,无则新增
///
///
///
Task> SaveAsync(CustomerEntity entity,bool isCommit = true);
}
}
客户服务接口实现
namespace test.BLL.Basic
{
internal class CommandCustomerServiceImpl : ICommandCustomerService, IAutoInject
{
private readonly ICustomerUnitOfWork unitOfWork;
public CommandCustomerServiceImpl(ICustomerUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
#region 插入
///
/// 插入单个实体
///
///
///
public async Task> InsertAsync(CustomerEntity entity,bool isCommit = true)
{
HttpResponseResultModel httpResponseResultModel = new HttpResponseResultModel { IsSuccess = false };
unitOfWork.RegisterInsert(entity);
if (isCommit)
{
await CommitAsync();
}
httpResponseResultModel.BackResult = entity.Id;
httpResponseResultModel.IsSuccess = true;
return httpResponseResultModel;
}
///
/// 批量插入实体
///
///
///
public async Task> InsertBatchAsync(List entityList,bool isCommit = true)
{
HttpResponseResultModel httpResponseResultModel = new HttpResponseResultModel { IsSuccess = false };
unitOfWork.RegisterInsertBatch(entityList);
if (isCommit)
{
await CommitAsync();
}
httpResponseResultModel.BackResult = true;
httpResponseResultModel.IsSuccess = true;
return httpResponseResultModel;
}
#endregion
#region 更新
///
/// 根据主键更新实体
///
///
///
public async Task> UpdateAsync(CustomerEntity entity,bool isCommit = true)
{
HttpResponseResultModel httpResponseResultModel = new HttpResponseResultModel { IsSuccess = false };
unitOfWork.RegisterUpdate(entity);
if (isCommit)
{
await CommitAsync();
}
httpResponseResultModel.IsSuccess = true;
return httpResponseResultModel;
}
///
/// 批量更新实体
///
///
///
public async Task> UpdateBatchAsync(List entityList,bool isCommit = true)
{
HttpResponseResultModel httpResponseResultModel = new HttpResponseResultModel { IsSuccess = false };
unitOfWork.RegisterUpdateBatch(entityList);
if (isCommit)
{
await CommitAsync();
}
httpResponseResultModel.IsSuccess = true;
return httpResponseResultModel;
}
///
/// 更新实体的部分字段
///
///
///
///
public async Task> UpdateFieldsAsync(CustomerEntity entity, List fields, bool isCommit = true)
{
HttpResponseResultModel httpResponseResultModel = new HttpResponseResultModel { IsSuccess = false };
unitOfWork.RegisterUpdateByFields(entity, fields);
if (isCommit)
{
await CommitAsync();
}
httpResponseResultModel.IsSuccess = true;
return httpResponseResultModel;
}
///
/// 根据id集合更新某个字段更新
///
///
///
///
///
public async Task> UpdateSingleFieldByIdsAsync(List idList, KeyValuePair column, bool isCommit = true)
{
HttpResponseResultModel httpResponseResultModel = new HttpResponseResultModel { IsSuccess = false };
unitOfWork.RegisterUpdateSingleFieldByIds(idList, column);
if (isCommit)
{
await CommitAsync();
}
httpResponseResultModel.IsSuccess = true;
return httpResponseResultModel;
}
#endregion
#region 删除
///
/// 根据根据主键删除
///
/// 主键
///
public async Task> DeleteAsync(long id,bool isCommit = true)
{
HttpResponseResultModel httpResponseResultModel = new HttpResponseResultModel { IsSuccess = false };
unitOfWork.RegisterDelete(id);
if (isCommit)
{
await CommitAsync();
}
httpResponseResultModel.IsSuccess = true;
return httpResponseResultModel;
}
///
/// 批量删除 根据主键
///
/// 主键集合
///
public async Task> DeleteBatchAsync(IList idList,bool isCommit = true)
{
HttpResponseResultModel httpResponseResultModel = new HttpResponseResultModel { IsSuccess = false };
unitOfWork.RegisterDeleteBatch(idList);
if (isCommit)
{
await CommitAsync();
}
httpResponseResultModel.IsSuccess = true;
return httpResponseResultModel;
}
#endregion
///
/// 保存实体,有则更新,无则新增
///
///
///
public async Task> SaveAsync(CustomerEntity entity,bool isCommit = true)
{
HttpResponseResultModel httpResponseResultModel = new HttpResponseResultModel { IsSuccess = false };
return httpResponseResultModel;
}
#region 事务
///
/// 事务
///
///
public async Task CommitAsync()
{
await unitOfWork.CommitAsync().ConfigureAwait(false);
}
#endregion
}
}
using System.Net;
namespace test.Core
{
///
/// http请求结果类
///
///
public class HttpResponseResultModel
{
///
/// http码
///
public HttpStatusCode HttpStatusCode { get; set; }
///
/// 是否成功
///
public bool IsSuccess { get; set; }
///
/// 返回结果
///
public T BackResult { get; set; }
///
/// 错误信息
///
public string ErrorMessage { get; set; }
///
/// 异常信息
///
public string ExceptionMessage { get; set; }
}
}
.NET Core 工作单元unitofwork 实现,基于NPOCO
标签:批量 ddc uri lse reading 循环 标识 基于接口 基础
原文地址:https://www.cnblogs.com/binbinxu/p/13061726.html