OnionArch - 如何实现更新指定字段的通用Handler
博主最近失业在家,找工作之余,自己动手写了个洋葱架构(整洁架构)解决方案,以总结和整理以前的项目经验,起名叫OnionArch,其目的是为了更好的实现采用DDD(领域驱动分析)和命令查询职责分离(CQRS)的洋葱架构。
什么是OnionArch
OnionArch解决方案清晰的展示了程序各分层的职责,帮助程序员写出逻辑更清晰的代码,提高程序的高内聚、低耦合性。提高程序逻辑的可重用性,可扩展性和可测试性。
OnionArch可降低单个微服务,特别是SAAS微服务开发的复杂度,在保证软件质量的基础上提高软件开发效率。
OnionArch基于最新的开源.Net 7.0 RC1, 数据库采用PostgreSQL, 目前实现了包括多租户在内的12个特性。详细内容请看:https://www.cnblogs.com/xiaozhuang/p/16772485.html
OnionArch如何实现更新指定字段的通用Handler
本篇主要讲述OnionArch如何实现更新指定字段的通用Handler,这里的Handler是指MediatR中继承IRequestHandler接口的处理逻辑。
Let me show you the code:
public async override Task<UpdateProductReply> UpdateProduct(UpdateProductRequest request, ServerCallContext context)
{
UpdateCommand<UpdateProductRequest> updateProductCommand = new UpdateCommand<UpdateProductRequest>(Guid.Parse(request.ProductId),request,p => p.Description);
await _mediator.Send(updateProductCommand);
return new UpdateProductReply()
{
Message = "Update Product sucess"
};
}
这是一个实现UpdateProduct业务用例的GRPC方法,新建一个UpdateCommand更新命令,并传入ProductId和要更新的数据request(表单提交的ViewModel),以及要更新的属性字段。然后调用Mediator.Send发送该命令即可。
UpdateCommand命令定义如下,继承自CQRS的ICommand接口,并采用了C#的record类型,确保必填字段不为空。
public record UpdateCommand<TModel>(Guid Id, TModel Model, params Expression<Func<TModel, object>>[] UpdateProperties) : ICommand
{ }
第三个参数可以传入多个要更新的字段的Lambda 表达式,不采用字符串List的方式以防止程序员写错。
Mediator的更新命令处理对象UpdateCommandHandler 接收到该命令进行处理:
public class UpdateCommandHandler<TModel, TEntity> : IRequestHandler<UpdateCommand<TModel>> where TEntity : BaseEntity
{
private readonly CURDDomainService<TEntity> _curdDomainService; public UpdateCommandHandler(CURDDomainService<TEntity> curdDomainService)
{
_curdDomainService = curdDomainService;
} public async Task<Unit> Handle(UpdateCommand<TModel> request, CancellationToken cancellationToken)
{
TEntity updateEntity = await _curdDomainService.Retrieve(request.Id);
updateEntity = request.Model.Adapt(updateEntity);
List<string> updateProperties = new List<string>();
foreach (var expression in request.UpdateProperties)
{
var member = expression.Body as MemberExpression;
if (member != null)
updateProperties.Add(member.Member.Name);
}
await _curdDomainService.Update(updateEntity, updateProperties);
return Unit.Value;
}
}
首先根据传入的ProductId获取到Product实体,然和将传入的request Model数据,通过Mapster的Adapt方法赋值给该实体,该实体字段就有了最新的值。
然后将传入的要更新的属性字段Lambda 表达式转换为属性字符串List,再调用领域层方法保存该实体到数据库。
领域层更新实体的仓储方法如下:
public async Task<TEntity> Update(TEntity entity, IEnumerable<string> updateProperties)
{
var entry = _dbContext.ChangeTracker.Entries<TEntity>().FirstOrDefault(p => p.Entity == entity);
if (entry == null)
{
entry = _dbContext.Set<TEntity>().Attach(entity);
}
entry.State = EntityState.Unchanged;
foreach (var updateProperty in updateProperties)
{
entry.Property(updateProperty).IsModified = true;
}
return entry.Entity;
}
可以看到,该方法只将要更新的字段设置为IsModified = true,即可达到更新特定字段的目的。
输出的SQL语句如下:
Executed DbCommand (11ms) [Parameters=[@p3='?' (DbType = Guid), @p0='?', @p1='?' (DbType = DateTime), @p2='?'], CommandType='Text', CommandTimeout='30']
UPDATE "T_Product" SET "Description" = @p0, "LastModified" = @p1, "LastModifiedBy" = @p2
WHERE "Id" = @p3;
可以看到,SQL只更新了Description字段,LastModified和LastModifiedBy字段是OnionArch的实体数据审计特性自动加上的。打完收工。
找工作时间
接下来又到了找工作广告时间:
博主有15年以上的软件技术实施经验(Technical Leader),专注于微服务和云原生(K8s)软件架构设计、专注于 .Net Core\Java开发和Devops构建发布。
博主10年以上的软件交付管理经验(Project Manager & Product Ower),致力于敏捷(Scrum)项目管理、软件产品业务需求分析和原型设计。
博主熟练配置和使用 Microsoft Azure云。
博主为人诚恳,积极乐观,工作认真负责。
我家在广州,也可以去深圳工作。做架构和项目管理都可以,希望能从事稳定行业的业务数字化转型。有工作机会推荐的朋友可以加我微信 15920128707,微信名字叫Jerry。
OnionArch - 如何实现更新指定字段的通用Handler的更多相关文章
- EF更新指定字段.或个更新整个实体
EF更新指定字段.或个更新整个实体 更新整个实体: public bool Update(Company compay) { if (compay != null) { dbContext.Entry ...
- 关于EF更新数据库,更新指定字段的设置
1.关于EF跟新数据库更新指定字段的设置 在EF提交到数据库的时候或许某些字段不想更新.或者自己更新一个模型到数据库去! 1.更新数据不更新一些字段 /// <summary> /// 数 ...
- MongoDB学习笔记~为IMongoRepository接口更新指定字段
回到目录 对于MongoDB来说,它的更新建议是对指定字段来说的,即不是把对象里的所有字段都进行update,而是按需去更新,这在性能上是最优的,这当然也是非常容易理解的,我们今天要实现的就是这种按需 ...
- EF更新指定字段...
EF更新指定的字段... 搜来搜去发现没有自己想要的啊... 或许本来就有更好的办法来实现我这个,所以没有人来搞吧... 如果有,请不吝告知..GG.. //要更改UserInfo表中指定的列,比如这 ...
- EF扩展 更新指定字段
using System.Data.Entity.Infrastructure; using System.Threading.Tasks; /// <summary> /// EF扩展 ...
- MySQL存储过程(更新指定字段的数据)
mysql存储过程示例: USE 数据库名称;DROP PROCEDURE IF EXISTS 数据库名称.存储过程名称;delimiter $$CREATE PROCEDURE 数据库名称.存储过程 ...
- entity framework 5 更新指定字段
dbSet.Attach(good); var stateEntry = ((IObjectContextAdapter)context).ObjectContext. ObjectStateMana ...
- C#实体更新指定的字段
接口类: /// <summary> /// 更新指定字段 /// </summary> /// <param name="entity">实体 ...
- Entity Framework 通过Lambda表达式更新指定的字段
本来需要EF来更新指定的字段,后来在园子里找到了代码 var StateEntry = ((IObjectContextAdapter)dbContext).ObjectContext.ObjectS ...
随机推荐
- FTP 基础 与 使用 Docker 搭建 Vsftpd 的 FTP 服务
FTP 基础 与 使用 Docker 搭建 Vsftpd 的 FTP 服务 前言 最近的工作中,需要将手机上的文件发送到公司的 FTP 的服务器.按照从前的思路,自然是,先将文件传到电脑,再由电脑上传 ...
- 论文翻译:2020_Lightweight Online Noise Reduction on Embedded Devices using Hierarchical Recurrent Neural Networks
论文地址:基于分层递归神经网络的嵌入式设备轻量化在线降噪 引用格式:Schröter H, Rosenkranz T, Zobel P, et al. Lightweight Online Noise ...
- 记录一个i变量引发的事故
概述 近期开发中遇到一个特别的问题,觉得很有必要与你下来.就是由于在开发中一个很小的疏忽,导致了很大的问题,是什么呢? 现象 我的程序突然引发了v8内部的错误,提示都是c++的,如下.程序一启动就直接 ...
- SpringBoot项目搭建 + Jwt登录
临时接了一个小项目,有需要搭一个小项目,简单记录一下项目搭建过程以及整合登录功能. 1.首先拿到的是一个码云地址,里面是一个空的文件夹,只有一个 2. 拿到HTTPS码云项目地址链接,在IDEA中cl ...
- Aoac唤醒的软件方案
Aoac唤醒 这篇文章包含了Win10下的Aoac唤醒和Win11下的Aoac唤醒的不同地方,在结尾处: 从Win10时代开始,通过软件来唤醒机器是一个很常见的事情了,但是很少有文档去将如何通过AOA ...
- E - Road Reduction
E - Road Reduction (atcoder.jp) 题意:一棵树n个点,m条路, di表示1-i的距离,问怎么选择边可以使得d2+...dn最短. 题解: 很明显,就是直接套最短路板子,判 ...
- 第四十一篇:Vue生命周期(二)
好家伙,书接上回 上图:(Vue官网中Vue实例图片的下半张) 以下为解释: 5.1.1. mounted执行完后,表示整个Vue实例已经初始化完毕了; 此时,组件已经脱离了创建阶段;进入到运行阶段 ...
- C与C++有什么区别
C是一个结构化语言,它的侧重点在于算法和数据结构.对语言本身而言,C是C++的一个子集. C程序的设计首要考虑的是如何通过一个过程,对输入进行运算处理,得到输出. 对于C++,首要考虑的是如何构造一个 ...
- ERROR: column "xxxxxx" does not exist解决办法
今天在写PostgreSQL语句时候发现运行这个代码 SELECT t1.equipid, t2.equipname, t1.bigtype, t1.smalltype FROM pdw_gh_pro ...
- docker注册中心相关操作
相关命令详解 (1)push推送 将镜像推送到由其名称或标签指定的仓库中.与pull命令相对. [root@docker ~]# docker push --help Usage: docker pu ...