基于SqlSugar的开发框架循序渐进介绍(24)-- 使用Serialize.Linq对Lambda表达式进行序列化和反序列化
在上篇随笔《基于SqlSugar的开发框架循序渐进介绍(23)-- Winform端管理系统中平滑增加对Web API对接的需求》中介绍了基于一个接口,实现对两种不同接入方式(直接访问数据库实现,基于Web API代理类实现)的处理,由于定义的接口中,我们为了方便,也是用了Lambda表达式的进行一些参数的处理,那么如果在Web API代理类中,Lambda表达式是不能直接传递给Web API的控制器的,那么如何对这个Lambda表达式进行序列化和反序列化还原就是一个急需解决的问题。 本篇随笔介绍采用Serialize.Linq 第三方组件的方式实现对Lambda表达式进行序列化和反序列化的处理。
1、Lambda表达式的接口使用
Lambda 表达式本质上是一个匿名函数,是C#中一种特殊语法,它的引入,使得匿名方法更加简单易用,最直接的是在方法体内调用代码或者为委托传入方法体的形式与过程变得更加优雅。 使用Lambda表达式可大大减少代码量,使得代码更加的优美、简洁,更有可观性。由于Lambda表达式的便利性,因此虽然在整合多个接入实现比较麻烦一些,我依旧希望通过寻找方法实现对Lambda表达式的兼容处理。
例如,以下就是一个根据名称简单进行判断的Lambda表达式的处理。
- /// <summary>
- /// 新增状态下的数据保存
- /// </summary>
- /// <returns></returns>
- public async override Task<bool> SaveAddNew()
- {
- CustomerInfo info = tempInfo;//必须使用存在的局部变量,因为部分信息可能被附件使用
- SetInfo(info);
- try
- {
- #region 新增数据
- //检查是否还有其他相同关键字的记录
- bool isExist = await BLLFactory<ICustomerService>.Instance.IsExistAsync(s=> s.Name.Equals(info.Name));
- if (isExist)
- {
- MessageDxUtil.ShowTips("指定的【姓名】已经存在,不能重复添加,请修改");
- return false;
- }
- var success = await BLLFactory<ICustomerService>.Instance.InsertAsync(info);
- if (success)
- {
- //可添加其他关联操作
- return true;
- }
- #endregion
- }
- catch (Exception ex)
- {
- LogTextHelper.Error(ex);
- MessageDxUtil.ShowError(ex.Message);
- }
- return false;
- }
它的函数原型就是一个Lambda表达式,如下所示的定义
- /// <summary>
- /// 判断是否存在指定条件的记录
- /// </summary>
- /// <param name="input">表达式条件</param>
- /// <returns></returns>
- Task<bool> IsExistAsync(Expression<Func<TEntity, bool>> input);
有些稍微复杂一点的函数,如下定义所示。
- /// <summary>
- /// 获取某字段数据字典列表
- /// </summary>
- Task<List<string>> GetFieldList(Expression<Func<TEntity, object>> selector, Expression<Func<TEntity, bool>> where = null);
调用的时候,如下所示。
- /// <summary>
- /// 初始化数据字典
- /// </summary>
- private async void InitDictItem()
- {
- //初始化代码
- var list = await BLLFactory<IFormService>.Instance.GetFieldList(s=> s.Category);
- this.txtCategory.BindDictItems(list, "");
- }
不过简单是简单了,但是本身Lambda表达式不能直接传递给Web API端参数,因为它无法直接序列化进行传递。
我们在之前说过,接入两种不同的数据提供方式。
因此我们为了继续使用Lambda表达是的优点,就需要使用Serialize.Linq对Lambda表达式进行序列化和反序列化。这样就可以在Web API端和Web API 代理端对Lambda表达式进行正常的使用了。
2、采用Serialize.Linq 对Lambda表达式进行序列化和反序列化的处理
首先在需要的地方,引入Serialize.Linq对Lambda表达式进行序列化和反序列化处理。
为了更好通用的实现Lambda表达式的正常序列化为文本,以及对文本的反序列化到Lambda表达式,我们这里编写了一个扩展函数,以便更方便的处理。
- /// <summary>
- /// 对Lambda表达式的序列号和反序列化处理
- /// </summary>
- public static class SerializeExtension
- {
- /// <summary>
- /// 序列化 LINQ Expression 表达式为JSON文本
- /// </summary>
- /// <typeparam name="TEntity">处理对象类型</typeparam>
- /// <typeparam name="TResult">返回结果类型</typeparam>
- /// <param name="express"></param>
- /// <returns></returns>
- public static string SerializeText<TEntity, TResult>(this Expression<Func<TEntity, TResult>> express)
- {
- //使用Serialize.Linq组件序列化表达式,传递给API端,API端需要对应反序列化的处理操作进行转换Expression
- var serializer = new ExpressionSerializer(new JsonSerializer());
- var expressJson = serializer.SerializeText(express);
- //接收端的反序列化处理
- //var express = (Expression<Func<TEntity, TResult>>)serializer.DeserializeText(expressJson);
- return expressJson;
- }
- /// <summary>
- /// 反序列化JSON文本为LINQ Expression 表达式
- /// </summary>
- /// <typeparam name="TEntity">处理对象类型</typeparam>
- /// <typeparam name="TResult">返回结果类型</typeparam>
- /// <param name="text"></param>
- /// <returns></returns>
- public static Expression<Func<TEntity, TResult>> DeserializeText<TEntity, TResult>(this string json)
- {
- Expression<Func<TEntity, TResult>> express = null;
- if (!string.IsNullOrWhiteSpace(json))
- {
- var serializer = new ExpressionSerializer(new JsonSerializer());
- express = (Expression<Func<TEntity, TResult>>)serializer.DeserializeText(json);
- }
- return express;
- }
- }
这样我们来看看两个对Lambda表达式的Web API代理类的封装处理代码
- /// <summary>
- /// 根据条件,获取所有记录
- /// </summary>
- public virtual async Task<ListResultDto<TEntity>> GetAllAsync(Expression<Func<TEntity, bool>> input, string orderBy = null)
- {
- var express = input.SerializeText(); //使用扩展函数处理生成JSON
- var postData = new
- {
- express,
- orderBy
- };
- return await DoActionAsync<ListResultDto<TEntity>>("all-expression", postData, HttpVerb.Post);
- }
- /// <summary>
- /// 根据条件计算记录数量
- /// </summary>
- /// <returns></returns>
- public virtual async Task<long> CountAsync(Expression<Func<TEntity, bool>> input)
- {
- var expressJson = input.SerializeText(); //使用扩展函数处理生成JSON
- return await DoActionAsync<long>("count-expression", expressJson, HttpVerb.Post);
- }
而对应的在Web API的基类控制器中,我们对这个通用的实现处理下就可以了
- /// <summary>
- /// 根据条件,获取所有记录
- /// </summary>
- [HttpPost]
- [Route("all-expression")]
- public async Task<ListResultDto<TEntity>> GetAllAsync(ExpressionOrderDto input)
- {
- ListResultDto<TEntity>? result = null;
- string json = input.expression;
- var express = json.DeserializeText<TEntity, bool>();
- if (express != null)
- {
- result = await _service.GetAllAsync(express!);
- }
- return result;
- }
- [HttpPost]
- [Route("count-expression")]
- public virtual async Task<long> CountAsync(dynamic expressJson)
- {
- long result = 0;
- string json = expressJson;
- var express = json.DeserializeText<TEntity, bool>();
- if (express != null)
- {
- result = await _service.CountAsync(express!);
- }
- return result;
- }
这样在服务器端的Web API控制器上,就还原了原先的Lambda表达式,可以正常的接收到客户端提交的条件处理了。
通过这样的迂回的方式,我们就可以在常规的接口,以及Web API的代理类中,都可以使用到Lambda表达式带来的便利性了,而不需要为了兼容而抛弃Lambda表达式接口参数的方式了。
基于SqlSugar的开发框架循序渐进介绍(24)-- 使用Serialize.Linq对Lambda表达式进行序列化和反序列化的更多相关文章
- 基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口
在基于SqlSugar的开发框架中,我们设计了一些系统服务层的基类,在基类中会有很多涉及到相关的数据处理操作的,如果需要跟踪具体是那个用户进行操作的,那么就需要获得当前用户的身份信息,包括在Web A ...
- 基于SqlSugar的开发框架循序渐进介绍(17)-- 基于CSRedis实现缓存的处理
在一个应用系统的开发框架中,往往很多地方需要用到缓存的处理,有些地方是为了便于记录用户的数据,有些地方是为了提高系统的响应速度,如有时候我们在发送一个短信验证码的时候,可以在缓存中设置几分钟的过期时间 ...
- 基于SqlSugar的开发框架循序渐进介绍(3)-- 实现代码生成工具Database2Sharp的整合开发
我喜欢在一个项目开发模式成熟的时候,使用代码生成工具Database2Sharp来配套相关的代码生成,对于我介绍的基于SqlSugar的开发框架,从整体架构确定下来后,我就着手为它们量身定做相关的代码 ...
- 基于SqlSugar的开发框架循序渐进介绍(4)-- 在数据访问基类中对GUID主键进行自动赋值处理
我们在设计数据库表的时候,往往为了方便,主键ID一般采用字符串类型或者GUID类型,这样对于数据库表记录的迁移非常方便,而且有时候可以在处理关联记录的时候,提前对应的ID值.但有时候进行数据记录插入的 ...
- 基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转
在前面随笔,我们介绍过这个基于SqlSugar的开发框架,我们区分Interface.Modal.Service三个目录来放置不同的内容,其中Modal是SqlSugar的映射实体,Interface ...
- 基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录
在我们对数据进行重要修改调整的时候,往往需要跟踪记录好用户操作日志.一般来说,如对重要表记录的插入.修改.删除都需要记录下来,由于用户操作日志会带来一定的额外消耗,因此我们通过配置的方式来决定记录那些 ...
- 基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理
在早期的随笔就介绍过,把常规页面的内容拆分为几个不同的组件,如普通的页面,包括列表查询.详细资料查看.新增资料.编辑资料.导入资料等页面场景,这些内容相对比较独立,而有一定的代码量,本篇随笔介绍基于V ...
- 基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用
在我们实际项目开发过程中,往往需要根据实际情况,对组件进行封装,以更简便的在界面代码中使用,在实际的前端应用中,适当的组件封装,可以减少很多重复的界面代码,并且能够非常简便的使用,本篇随笔介绍基于El ...
- 基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用
刚完成一些前端项目的开发,腾出精力来总结一些前端开发的技术点,以及继续完善基于SqlSugar的开发框架循序渐进介绍的系列文章,本篇随笔主要介绍一下基于Vue3+TypeScript的全局对象的注入和 ...
- 基于SqlSugar的开发框架循序渐进介绍(15)-- 整合代码生成工具进行前端界面的生成
在前面随笔<基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理>中我们已经介绍过,对于相关的业务表的界面代码,我们已经尽可能把不同的业务逻辑 ...
随机推荐
- androidmanifest.xml 反编译
androidmanifest.xml 反编译 去除更新只修改androidmanifest.xml内容 解压apk文件后得到这个文件androidmanifest.xml windwos安装java ...
- CentOS 7 下安装 MySQL 8.x
CentOS 7 下安装 MySQL 8.x 作者:Grey 原文地址: 博客园:CentOS 7 下安装 MySQL 8.x CSDN:CentOS 7 下安装 MySQL 8.x 环境 CentO ...
- MasaFramework -- 异常处理
前言 在程序设计中,我们会遇到各种各样的异常问题,一个异常处理不仅仅可以帮助开发者快速的定位问题,也可以给用户更好的使用体验,那么我们在AspNetCore项目中如何捕获以及处理异常呢? 而对应Asp ...
- 齐博x1内容评论标签的风格制作
评论的标签如下: {qb:comment name="xxxxx" rows='5'} HTML代码片段 {/qb:comment} 评论涉及到的元素有{posturl} 这个是代 ...
- 痞子衡嵌入式:i.MXRT中FlexSPI外设不常用的读选通采样时钟源 - loopbackFromSckPad
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT中FlexSPI外设不常用的读选通采样时钟源 - loopbackFromSckPad. 最近碰到一个客户,他们在 i.MX ...
- python关于Django搭建简单博客项目(教程)
由于csdn各种django blog博文都有或多或少的bug,所以我决定自己写一篇,先附上教程,详解在另一篇博文里,为了便于大家复制粘贴,本文代码尽量不使用图片. 源代码及解析文章请在我的githu ...
- 这才是使用ps命令的正确姿势
这才是使用ps命令的正确姿势 前言 在linux系统当中我们通常会使用命令去查看一些系统的进程信息,我们最常使用的就是 ps (process status).ps 命令主要是用于查看当前正在运行的程 ...
- Vue报错:component has been registered but not used
原因: eslint代码检查到你注册了组件但没有使用,然后就报错了.比如代码: 比如Vue中注册了File组件,而实际上却没有使用到(直接取消注册为好): ... impor ...
- CF452F等差子序列 & 线段树+hash查询区间是否为回文串
记录一下一个新学的线段树基础trick(真就小学生trick呗) 给你一个1到n的排列,你需要判断该排列内部是否存在一个3个元素的子序列(可以不连续),使得这个子序列是等差序列.\(n\) <= ...
- 论文笔记 - An Explanation of In-context Learning as Implicit Bayesian Inference
这位更是重量级.这篇论文对于概率论学的一塌糊涂的我简直是灾难. 由于 prompt 的分布与预训练的分布不匹配(预训练的语料是自然语言,而 prompt 是由人为挑选的几个样本拼接而成,是不自然的自然 ...