动态拼接表达式——Expression

我们在项目中会遇到以下查询需求吗?

比如需要查询出满足以下条件的会员:

 条件组一:30-40岁的男性会员

 条件组二:20-30岁的女性会员

 条件组三:60-80岁性别未知的会员

 条件组内是并且关系,但是条件组与组之间是或者关系。 

很多程序员脑袋可能会直接蹦出用where拼接条件组的想法,就如同下面图片所展示的方法 :

         生成的SQl语句:

 

根据生成的sql语句我们会发现直接使用Where拼接出来的sql语句是并且的关系,

原本我们想要的结果是组与组之间是或者的关系,但是现在变成了并且的关系,很显然不满足我们的查询需求。

想要达到我们的查询需求,我们得使用动态拼接条件的方法,通常我会使用Expression

        最终我们生成的sql语句为:

 从查询语句可以看出达到了我们的查询需求,组与组之间是或者的关系。 

 以下是举例代码:       

namespace MyTest
{
    /// <summary>
    /// 动态拼接表达式
    /// </summary>
    public class ExpressionTest : ApplicationService
    {
        public readonly IRepository<CrmMember, int> _memberRep;
        public ExpressionTest(IRepository<CrmMember, int> memberRep)
        {
            _memberRep = memberRep;

        }


        /// <summary>
        /// 使用动态拼接-Expression
        /// </summary>       
        public async Task Test()
        {
            #region 描述

            /*         
             *  条件组一:30-40岁的男性会员
             * 条件组二:20-30岁的女性会员
             *  条件组三:60-80岁性别未知的会员
             *  条件组内是并且关系,但是条件组与组之间是或者关系。 
            */
            #endregion

            #region 封装查询条件

            var param = new List<SearchMemberInputDto>
            {
                new SearchMemberInputDto { Sex = 1, AgeStart = 30, AgeEnd = 40 },// 30-40岁的男性
                new SearchMemberInputDto { Sex = 2, AgeStart = 20, AgeEnd = 30 }, // 20-30岁的女性
                new SearchMemberInputDto { Sex = 0, AgeStart = 20, AgeEnd = 30 }// 60-80岁性别未知
            };

            #endregion

            #region 动态拼接-Expression

            var members = (await _memberRep.GetAllAsync()).Where(a => a.GroupId == AbpSession.GroupId && a.IsDeleted == false);

            Expression<Func<CrmMember, bool>> expressions = s => false;

            foreach (var item in param)
            {
                expressions = expressions.Or(s => s.Sex == item.Sex && s.Age >= item.AgeStart && s.Age <= item.AgeEnd);
            }

            members = members.Where(expressions);

            var memberList = members.ToList();

            #endregion
        }


        /// <summary>
        /// 测试错误的方法
        /// </summary>       
        public async Task TestError()
        {
            #region 描述

            /*         
             *  条件组一:30-40岁的男性会员
             * 条件组二:20-30岁的女性会员
             *  条件组三:60-80岁性别未知的会员
             *  条件组内是并且关系,但是条件组与组之间是或者关系。 
             *
             注意:此方法是一个错误的写法 达不到查询需求
            */

            #endregion

            #region 封装查询条件

            var param = new List<SearchMemberInputDto>
            {
                new SearchMemberInputDto { Sex = 1, AgeStart = 30, AgeEnd = 40 },// 30-40岁的男性
                new SearchMemberInputDto { Sex = 2, AgeStart = 20, AgeEnd = 30 }, // 20-30岁的女性
                new SearchMemberInputDto { Sex = 0, AgeStart = 20, AgeEnd = 30 }// 60-80岁性别未知
            };

            #endregion            

            var members = (await _memberRep.GetAllAsync()).Where(a => a.GroupId == AbpSession.GroupId && a.IsDeleted == false);

            foreach (var item in param)
            {
                members = members.Where(s => s.Sex == item.Sex && s.Age >= item.AgeStart && s.Age <= item.AgeEnd);
            }

            var memberList = members.ToList();

        }

    }

    /// <summary>
    /// 条件
    /// </summary>
    public class SearchMemberInputDto
    {

        /// <summary>
        /// 性别
        ///0-未知; 1-男;2-女
        /// </summary>
        public int Sex { get; set; }

        /// <summary>
        /// 年龄-开始值
        /// </summary>
        public int AgeStart { get; set; }

        /// <summary>
        /// 年龄-结束值
        /// </summary>
        public int AgeEnd { get; set; }
    }

}
View Code

    这个是很简单的一种用法,我这里只做了简单的讲述,希望对大家有所帮助。

本文转载于网络 如有侵权请联系删除

相关文章

  • 2021年7月总结

    大家好,又见面了,我是全栈君。1.页面中有如下代码片段:<imgsrc="x.jpg"id="img1"title="xx"sina_title=""alt="">复制使用javascript的什么方法获取节点对象:答:document.getElementsById(‘img1’)document.getElementsById(‘element’):可获取指定id对象集合,例如id为element的input标签对象。 document.getElementsByName(“element”):可获取带有指定名称的对象的集合,例如name为element的input标签对象。 document.getElementsByTagName(“Input”):可获取带有指定标签名的对象集合,例如input标签对象。 .parentNode表示获取其父节点对象,.childNodes表示获取其子节点对象。 varElement=document.getElementById(“u

  • 智慧船舶带来港口革命,可视化成为主力军

    前言中国的水运最早可追溯到新石器时代的独木舟和排筏,到宋朝时中国已形成完整的水运及港口体系。船也从舟筏时代过渡到柴油机船时代,“达飞·和风”号的交付,标志中国集装箱船取得长足发展。现在,中国的港口规模居世界首位,今年上半年,仅外贸一项的货物吞吐量高达235720万吨,集装箱吞吐量高达13818万标箱,港口和船舶的运作模式已由几千年的人力为主发展成为高度机械化、自动化和信息化。自动化港口和船舶依托新基建和新科技势能,积极抢抓数字化转型先机,把数据作为企业的核心资源,运用Hightopo自主研发的HTforWeb可视化产品,擦亮绿色发展底色,解决传统码头和船舶能耗高、成本高、污染大等问题。效果展示通过HT实现可交互式的Web三维场景,可进行缩放、平移、旋转、翻转,场景内各设备可以响应交互事件。结合HT引擎强大的渲染能力,保证场景在Web中高效流畅地加载运行并保证优秀的可视化效果。2D、3D无缝衔接,完美融合。注重细节刻画,点击相对应的设备能显示其作业等信息。船舶信息可视化货轮信息可视化每条船舶显示船名、船运公司、船型、驻泊计划、船长头像,易进行识别和管理。船舶的2D面板显示了航线、进口航次

  • 啃爹的 Chrome 错误代码net::ERR_UNSAFE_PORT

    最近调试程序遇到了个net::ERR_UNSAFE_PORT开始以为是跨域问题后来百度才发现是浏览器端口限制问题不想修改浏览器设置的就改用其它端口吧,搜索了一下,Firefox也有类似的端口限制;如果非要使用类似的端口,我们要做的是允许访问非常规端口地址,解决办法:选中GoogleChrome快捷方式,右键属性,在”目标”对应文本框添加:--explicitly-allowed-ports=87,6666,556,6667复制允许多个端口以逗号隔开,最终如下:C:\Users\Huoqing\AppData\Local\Google\Chrome\Application\chrome.exe--explicitly-allowed-ports=6666,556复制附录:GoogleChrome默认非安全端口列表,虽然以上方法可以解决问题,但建议尽量避免以下端口:1,//tcpmux 7,//echo 9,//discard 11,//systat 13,//daytime 15,//netstat 17,//qotd 19,//chargen 20,//ftpdata 21,//ft

  • LeetCode笔记:Weekly Contest 232 比赛记录

    0.赛后总结这一次的比赛久违的直接把4道题全部做出来了,耗时差不多40分钟,国内和国际排名都在前2%这个量级,就是很开心啦。继续加油吧!?1.题目一给出题目一的试题链接如下:5701.仅执行一次字符串交换能否使两个字符串相等1.解题思路这一题思路上来说非常的直接,仅一次交换就能使两字符串相同的充要条件为:两字符串要么字符完全相同,要么有且只有两个位置字符不同,且两者位置刚好相反。因此,我们基于此进行代码写作即可。2.代码实现给出python代码实现如下:classSolution: defareAlmostEqual(self,s1:str,s2:str)->bool: n,m=len(s1),len(s2) ifn!=m: returnFalse diff=[] foriinrange(n): ifs1[i]!=s2[i]: diff.append(i) iflen(diff)==0: returnTrue iflen(diff)==2ands1[diff[0]]==s2[diff[1]]ands1[diff[1]]==s2[diff[0]]: returnTrue retur

  • 在王者荣耀角度下分析面向对象程序设计B中23种设计模式之外观模式

    ·外观模式在王者荣耀中的应用·一、简述王者荣耀是由腾讯游戏天美工作室群开发并运行的一款运营在Android、IOS、NS平台上的MOBA类手机游戏。玩家在想要玩这款游戏时,直接点击王者荣耀APP图标启动即可,系统会自动调用并不需要玩家分别启动界面、音乐、更新安装包等。 无论在现实生活中还是在软件开发过程中,用户经常需要和多个对象打交道。如果不对这些对象通过一种方式组合,用户完成某项任务时就很不方便,于是我们可以通过"外观类"的角色来简化用户和多个对象之间的交互过程。 在本实例中,模拟玩家打开游戏的操作,玩家只需要点击APP的图标,系统就会自动调用一系列的功能模块进行游戏初始化。二、外观模式(FacadePattern)外观模式理解: 高度概括:为系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 一个大的系统一般都由若干个子系统构成,每个子系统包含多个类,这些类协同合作为用户提供所需要的功能。一个客户程序中的某个类的实例如果直接和子系统的多个类的实例打交道完成多项任务,就使客户程序中的类和子系统类有过多的依赖

  • helm部署mysql

    关于helm部署mysql如果您的kubernetes已有helm,那么部署mysql的步骤可用helm来简化,原先需要自己动手配置的deployment和service都已集成在chart中,今天就来实战通过helm部署mysql,并且将之前遇到的问题和解决方法列出来;环境信息硬件:三台CentOS7.7服务器kubernetes:1.15helm:2.16.1mysql:5.7.14关于helm的部署kubernetes环境helm的部署和基本操作请参考《部署和体验Helm(2.16.1版本)》下载chart包执行helmsearchmysql看看chart仓库有没有mysql,如下图,红框中就是我们需要的chart: 执行helmfetchstable/mysql,会在当前目录生成文件mysql-0.3.5.tgz执行tar-zxvfmysql-0.3.5.tgz,解压后生成文件夹mysql进入mysql文件夹,打开values.yaml文件,按需要进行设置如下图所示,红框1可以选择mysql镜像的TAG,红框2来设置root账号的密码,注意密码的字符串要加双引号: 下图红框1是

  • 1-3 Winform 中的常用控件(

    1-3Winform中的常用控件u本节学习目标:nSystem.Windows.Forms.Control基本结构n使用基本控件如标签、文本、按钮、列表框和组合框n掌握窗体的常用属性和方法n进行基本控件的开发设计工作n深入掌握系统对话框的属性及代码开发n掌握模式对话与非模式对话的概念及差异n了解模式对话的开发机理1-3-1简介Winform中的常用控件来自于系统System.Windows.Forms.Control,该类库来自System.Windows.Forms命名空间之内,该命名空间提供各种控件类,使用这些控件类,可以创建丰富的用户界面,具体实现功能由位于该命名空间下的Control系统类派生。Control类为在Form中显示的所有控件提供基本功能,Form类表示应用程序内的窗口。这包括对话框,无模式窗口和多文档界面(MDI)客户端窗口及父窗口,同时也可以通过从UserControl类派生而创建自己的控件。对于上述所有的这些可视化界面组件,我们统一称之为控件,这些控件都是源于System.Windows.Forms命名空间,该命名空间结构如图1-7。图1-7System.Wi

  • 节前有个好消息跟大家分享,腾讯云再获国家标准认证

    近日,国内首次基于《信息安全技术个人信息安全规范》等国家标准开展的认证结果正式公布。腾讯云作为首批试点单位,通过中国网络安全审查技术与认证中心(CCRC)开展的个人信息安全管理体系认证现场审核,成为中国首批通过该认证的云服务商。这也是腾讯云继以GDPR合规要求为基础的CISPE(欧洲云计算服务供应商联盟数据保护行为准则)认证之后,再次获得重量级个人信息保护能力认证,充分体现了腾讯云在保障客户个人信息安全方面的重视程度和领先能力。据悉,本次认证是《网络安全法》颁布之后,市场监督管理部门第一批针对国内企业进行的个人信息保护相关认证,以GB/T35273-2017《信息安全技术个人信息安全规范》为认证标准。通过认证的组织,将获得个人信息安全管理体系认证证书。腾讯云自2018年5月GB/T35273-2017《信息安全技术个人信息安全规范》正式实施之际,就开始落地践行国家标准,历经近一年时间,在2018年底首家通过国家检测认证机构的现场审核,并以云计算服务的认证范围,获得全国首批云服务商认证证书,再次验证了腾讯云在安全合规方面的能力。截至目前,腾讯云在国际标准、国内标准、牌照类、行业安全标准等

  • 一个事半功倍的Java反射库

    在Java和Android中,我们常常会使用反射来达到一些兼容的目的。Java原生提供的反射很是麻烦,使用起来很是不方便。比如我们想要调UserManager的静态方法get,使用原生的实现如下1 2 3 4 5 6 7 8 9 10 11try{ finalMethodm=UserManager.class.getMethod("get",Context.class); m.setAccessible(true); m.invoke(null,this); }catch(NoSuchMethodExceptione){ e.printStackTrace(); }catch(IllegalAccessExceptione){ e.printStackTrace(); }catch(InvocationTargetExceptione){ e.printStackTrace(); }实现起来好不麻烦。这其中需要确定方法名和参数来获取对应的Method对象设置Method对象的assessible为true调用invoke方法,并且传入对应的参数捕获其中可能抛出来的一

  • Android移动开发案例教程-第二章 Android开发起步_V0.2

    第二章Android开发起步_V0.2-001.png第二章Android开发起步_V0.2-002.png第二章Android开发起步_V0.2-003.png第二章Android开发起步_V0.2-004.png第二章Android开发起步_V0.2-005.png第二章Android开发起步_V0.2-006.png第二章Android开发起步_V0.2-007.png第二章Android开发起步_V0.2-008.png第二章Android开发起步_V0.2-009.png第二章Android开发起步_V0.2-010.png第二章Android开发起步_V0.2-011.png第二章Android开发起步_V0.2-012.png第二章Android开发起步_V0.2-013.png第二章Android开发起步_V0.2-014.png第二章Android开发起步_V0.2-015.png第二章Android开发起步_V0.2-016.png第二章Android开发起步_V0.2-017.png第二章Android开发起步_V0.2-018.png第二章Android开发起步

  • 软件性能测试分析与调优实践之路-Web中间件的性能分析与调优总结

    本文主要阐述软件性能测试中的一些调优思想和技术,节选自作者新书《软件性能测试分析与调优实践之路》部分章节归纳。 在国内互联网公司中,Web中间件用的最多的就是Apache和Nginx这两款了,包括很多大型电商网站淘宝、京东、苏宁易购等,都在使用Nginx或者Apache作为Web中间件。而且很多编程语言在做Web开发时,会将Apache或者Nginx作为其绑定的固定组件,比如php语言做Web开发时,就经常和Apache联系在一起,使得apche成为了php在Web开发时的一个标配。而Nginx不管是在作为Web静态资源访问管理或者作为动态的请求代理性能都是非常的高效,当然Nginx或者Apache在性能分析时,有时候也会存在性能瓶颈或者需要进行调优以支持更高的并发处理能力。 1.Nginx的性能分析和调优 1.1 Nginx的负载均衡策略的选择 在一般的时候,Web中间件最大的作用就是负责对请求进行分发,也就是我们常说的起到负载均衡的作用,当然负载均衡只是Nginx的作用之一,Nginx常见的负载均衡策略一般包括轮询、指定权重(weight)、ip_hash、least_c

  • Spark RDD详解

    1.RDD是什么 RDD(ResilientDistributedDataset):是Spark的核心数据结构,指的是一个只读的、可分区的分布式数据集,这个数据集的全部或部分可以缓存在内存中,在多次计算间重用。 RDD是只读的 RDD是分区记录的集合 RDD是容错的 RDD是高效的 RDD不需要物化 RDD可以缓存的 2.RDD的产生 1.传统的MapReduce虽然具有自动容错、平衡负载和可拓展性的优点,但是其最大缺点是采用非循环式的数据流模型,使得在迭代计算式要进行大量的磁盘IO操作。RDD正是解决这一缺点的抽象方法。 2.RDD的具体描述RDD(弹性数据集)是Spark提供的最重要的抽象的概念,它是一种有容错机制的特殊集合,可以分布在集群的节点上,以函数式编操作集合的方式,进行各种并行操作。可以将RDD理解为一个具有容错机制的特殊集合,它提供了一种只读、只能有已存在的RDD变换而来的共享内存,然后将所有数据都加载到内存中,方便进行多次重用。①它是分布式的,可以分布在多台机器上,进行计算。②它是弹性的,计算过程中内存不够时它会和磁盘进行数据交换。③这些限制可以极大的降

  • C# Datetime类常用技巧

    C#类常用技巧 //今天DateTime.Now.Date.ToShortDateString();//昨天,也就是今天的日期减一DateTime.Now.AddDays(-1).ToShortDateString();//明天,同理,加一DateTime.Now.AddDays(1).ToShortDateString();//本周(要知道本周第一天就得先知道今天是星期几,从而得知本周第一天就是几天前的那一天;每一周是从周日始至周六止[0-6])DateTime.Now.AddDays(Convert.ToDouble((0-Convert.ToInt16(DateTime.Now.DayOfWeek)))).ToShortDateString();//DateTime.Now.DayOfWeek获得今天是本周的第几天(0<=n<=6)DateTime.Now.AddDays(Convert.ToDouble((6-Convert.ToInt16(DateTime.Now.DayOfWeek)))).ToShortDateString();//中文显示星期几//由于Day

  • 【IoT】thingsboard3.3.3-源码编译环境,先对齐环境

        博客地址: http://www.cnblogs.com/defineconst/ 博客版权: 本文以学习、研究和分享为主,欢迎转载和各类爬虫,但必须在文章页面明显位置给出原文链接。 如果文中有不妥或者错误的地方还望高手的您指出,以免误人子弟。如果您有更好的建议,不如留言一起讨论,共同进步! 再次感谢您耐心的读完本篇文章。

  • 减少apk包大小的一种思路

    现在apk大小主要是决定于两个:一个是图片一个是.SO文件(这个尽量用release包),而对于图片,既要越小,又要保持质量。 之前是PNG-->JPG, 现在直接是PNG--->webp,orjpg-->webp 对于50KB以上的图,质量80%的话,都有2/3的压缩 大赞啊 只要android4.0+(level>=17)都可以的 但是有些图片尤其是720P下的图片,转成webp格式后,文件的大小反而变大了,所以这个没有绝对的。 此时需要权衡,建议此种情况下,不替换。   附:webp在线转换工具 https://webp-converter.com/   AndroidStudio2.3.X开始,已经内置了webp与PNG图片格式互相转换的工具了,而且还支持整个文件夹的转化 还可以设置参数哦:  

  • Anaconda官方网站下载慢的解决方法

    https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/ Anaconda是一个用于科学计算的Python发行版,支持Linux,Mac,Windows,包含了众多流行的科学计算、数据分析的Python包。 Anaconda安装包可以到 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 下载。 TUNA还提供了Anaconda仓库与第三方源(conda-forge、msys2、pytorch等,查看完整列表)的镜像,各系统都可以通过修改用户目录下的 .condarc文件。Windows用户无法直接创建名为 .condarc 的文件,可先执行 condaconfig--setshow_channel_urlsyes 生成该文件之后再修改。 注:由于更新过快难以同步,我们不同步pytorch-nightly, pytorch-nightly-cpu, ignite-nightly这三个包。 c

  • mac gcc运行文件

    步骤:创建C文件、用Vim编写C程序、编译C程序文件、执行编译后生成的.out文件。 1、$:touchHello.c//创建一个Hello.c文件(本目录下) 2、$:vimHello.c//用vim编辑Hello.c文件 i//打开vim后先输入i进入编辑状态 以下为vim中输入的程序*** intmain() { printf(“HelloMac!\n”); } ESC键//按ESC键退出编辑状态 :wq//先输入“:”,再输入“w”表示保存,最后输入“q”表示退出 复制 3、$:gccHello.c//编译Hello.c文件,会生成可执行文件“a.out” 4、$:./a.out//执行a.out

  • 面试第三篇

    1.python线程池原理? 我理解为线程池是一个存放很多线程的单位,同时还有一个对应的任务队列。 整个执行过程其实就是使用线程池中已有有限的线程把任务队列中的任务做完。这样做的好处就是你不需要为每个任务都创建一个线程, 因为当你创建第100个线程来执行第100个任务的时候,可能前面已经有50个线程结束工作了。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。 因此重复利用线程来执行任务,减少系统资源的开销。  复制 2.python合并字典,相同key的value如何相加? 合并两个字典的方法 方法1:dictMerged1=dict(dict1.items()+dict2.items()) 方法2:dictMerged2=dict(dict1,**dict2) 方法2等同于:dictMerged=dict1.copy() dictMerged.update(dict2) 或者dictMerged=dict(dict1) dictMerged.update(dict2) 复制 3.python中单下划线和双下划线 >>>classMyClass(

  • 【Qt开发】常用控件--QLineEdit

    QLineEdit是单行文本编辑控件。比如用户名,密码等输入框可以使用该控件。 所属头文件<QLineEdit>   常用方法 1.voidsetText(constQString&)   设置编辑框文本内容 2.voidsetReadOnly(bool)   控件设置为只读模式 3.voidsetPlaceholderText(constQString&)   设置编辑框中的默认提示信息 4.void setMaxLength(int)    设置编辑中输入的最大长度 5.voidsetEchoMode(EchoMode)   设置编辑框的输入模式   QLineEdit::Normal:默认模式,输入与现实一致   QLineEdit::Password:密码模式,输入的内容用黑点代替,无法看到输入的内容        QLineEdit::PasswordEchoOnEdit:编辑时内容可现实,否则为密码模式   QLineEdit::NoEcho:输入不可见 6.void setAlignment(Qt::Al

  • 软件测试培训分享:国内好用的5款软件测试管理工具

    不管是新手还是有经验的软件测试人员,都需要一个好的软件测试管理工具,可以大大的提高自己的工作效率,那么以下小编为大家介绍的软件测试培训教程就是国内好用的5款软件测试管理工具推荐。软件测试培训分享:国内好用的5款软件测试管理工具   写好测试用例是做好测试的前提,写测试用例需要一个有用的测试管理工具。外国有几款不错的测试管理工具,因为服务器部署在国外,国内访问会比较卡,还有就是语言不是中文大家用起来比较困难,这里就不推荐大家使用。以下为大家推荐5款比较好用的国内测试管理工具。   1.Bugzilla   Bugzilla是一款缺陷管理工具,是一款更轻量级的工具,在国内用户比较多。近几年来,Bugzilla不仅在缺陷管理方面不断优化产品,而且也逐步完善了测试管理的其它领域,如测试用例管理、测试流程管理、产品需求管理等,实现了测试的集成管理。   2.TestLink   TestLink是一个开放源码的测试管理工具,可以进行测试用例管理、测试过程管理、测试结果管理,有条件的团队可以进行二次开发,满足自己测试团队的需求。   3、Jackson   Jackson是一款集成研发管理工具,它

  • vue获取授权url

    1.在Vue页面加载时动态发送请求获取微博授权url 1.1在components\common\lab_header.vue中写oauth动态获取微博授权URL //获取微博登录地址 oauth(){ //从后端获取微博登录地址 oauth_post().then((resp)=>{ console.log(resp) //{'code':'0','msg':'成功','data':{'url':url}} leturl=resp.data.url; this.weibo_url=url; }) } 1.2在vue的mounted函数中调用获取微博授权url函数 mounted(){ this.oauth() }, 1.3点击"登录"弹出的form表单中加入url ```

相关推荐

推荐阅读