c# Expression 扩展

简介: 一、简介 当查询比较复杂时,需要很多判断或者跨方法传递参数时使用 二、扩展类 /// /// Expression表达式扩展操作类 /// 调用方法:repository.

一、简介

当查询比较复杂时,需要很多判断或者跨方法传递参数时使用

二、扩展类

/// <summary>
    ///     Expression表达式扩展操作类
    /// 调用方法:repository.GetAll().AsExpandable().Where(predicate)
    /// </summary>
    public static class ExpressionExtensions
    { 
        /// <summary>
        ///     以特定的条件运行组合两个Expression表达式
        /// </summary>
        /// <typeparam name="T">表达式的主实体类型</typeparam>
        /// <param name="first">第一个Expression表达式</param>
        /// <param name="second">要组合的Expression表达式</param>
        /// <param name="merge">组合条件运算方式</param>
        /// <returns>组合后的表达式</returns>
        public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second,
            Func<Expression, Expression, Expression> merge)
        {
            var map =
                first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
            var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
            return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
        }

        /// <summary>
        ///     以 Expression.AndAlso 组合两个Expression表达式
        /// </summary>
        /// <typeparam name="T">表达式的主实体类型</typeparam>
        /// <param name="first">第一个Expression表达式</param>
        /// <param name="second">要组合的Expression表达式</param>
        /// <returns>组合后的表达式</returns>
        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first,
            Expression<Func<T, bool>> second)
        {
            return first.Compose(second, Expression.AndAlso);
        }

        /// <summary>
        ///     以 Expression.OrElse 组合两个Expression表达式
        /// </summary>
        /// <typeparam name="T">表达式的主实体类型</typeparam>
        /// <param name="first">第一个Expression表达式</param>
        /// <param name="second">要组合的Expression表达式</param>
        /// <returns>组合后的表达式</returns>
        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first,
            Expression<Func<T, bool>> second)
        {
            return first.Compose(second, Expression.OrElse);
        }

        private class ParameterRebinder : ExpressionVisitor
        {
            private readonly Dictionary<ParameterExpression, ParameterExpression> _map;

            private ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
            {
                _map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
            }

            public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map,
                Expression exp)
            {
                return new ParameterRebinder(map).Visit(exp);
            }

            protected override Expression VisitParameter(ParameterExpression node)
            {
                ParameterExpression replacement;
                if (_map.TryGetValue(node, out replacement))
                    node = replacement;
                return base.VisitParameter(node);
            }
        }
    }

 

三、如何使用

1.关于引用

using System.Linq;
using System.Linq.Expressions;

using LinqKit;

还需要引入扩展类的命名空间

2.使用示例

            Expression<Func<User, bool>> pre;
            pre = s => s.NickName.Contains("");
            pre = pre.Or(s => s.NickName.Contains(""));
            pre = pre.And(s => s.CompanyId == "1");
var data = _userRepository.GetAll().AsExpandable().Where(pre);

 

相关文章
|
1月前
|
C# Python
使用wxpython开发跨平台桌面应用,对wxpython控件实现类似C#扩展函数处理的探究
【10月更文挑战第30天】使用 `wxPython` 开发跨平台桌面应用时,可以通过创建辅助类来模拟 C# 扩展函数的功能。具体步骤包括:1. 创建辅助类 `WxWidgetHelpers`;2. 在该类中定义静态方法,如 `set_button_color`;3. 在应用中调用这些方法。这种方法提高了代码的可读性和可维护性,无需修改 `wxPython` 库即可为控件添加自定义功能。但需要注意显式调用方法和避免命名冲突。
|
7月前
|
开发框架 .NET C#
C# 10.0中的扩展属性与模式匹配:深入解析
【1月更文挑战第20天】C# 10.0引入了众多新特性,其中扩展属性与模式匹配的结合为开发者提供了更强大、更灵活的类型检查和代码分支能力。通过这一特性,开发者可以在不修改原始类的情况下,为其添加新的行为,并在模式匹配中利用这些扩展属性进行更精细的控制。本文将详细探讨C# 10.0中扩展属性与模式匹配的工作原理、使用场景以及最佳实践,帮助读者更好地理解和应用这一新功能。
|
Oracle 架构师 关系型数据库
C#反射应用之实现动态可配置可扩展框架的简单示例
C#反射应用之实现动态可配置可扩展框架的简单示例
|
Oracle 关系型数据库 MySQL
超简单的C#可配置可扩展基础框架示例
超简单的C#可配置可扩展基础框架示例
|
C# Windows
推荐一个C#开发的窗口扩展菜单,支持系统所有窗口
一个C#开发的窗口扩展项目,采用.NET Framework 4.0开发,支持Windows Xp以及更高版本的系统,同时支持命令模式,可供代码调用。
127 0
推荐一个C#开发的窗口扩展菜单,支持系统所有窗口
|
测试技术 程序员 API
一个方便IO单元测试的C#扩展库
一个支持IO实现单元测试的扩展库,支持跨平台,与File所有API接口都一样,方便我们项目扩展、迁移。
101 0
一个方便IO单元测试的C#扩展库
|
开发框架 程序员 API
【C#】.net core2.1,通过扩展状态代码页方法对404页面进行全局捕抓并响应信息
在开发一个网站项目时,除了异常过滤功能模块,还需要有针对404不存在的api接口和页面处理功能 本篇文章就来讲讲,如何自定义全局请求状态类来统一处理
230 0
|
前端开发 程序员 C#
【C#】通过扩展对象的方式,对字符串等数据类型进行数据进一步处理
在本篇文章中,我们讲一起了解下对象扩展的使用 在实际项目开发中,对象扩展使用的场景还是挺多的,比如:需要对时间值进行再处理,或者字符串中的斜杠(/)转为反斜杠(\)
118 0
|
Linux C# 数据安全/隐私保护
Python3 与 C# 扩展之~模块专栏
  代码裤子:https://github.com/lotapp/BaseCode/tree/maste 在线编程:https://mybinder.org/v2/gh/lotapp/BaseCode/master 在线预览:http://github.
2277 0
|
C# UED
c#开发移动APP-Xamarin入门扩展剖析
原文:c#开发移动APP-Xamarin入门扩展剖析   上节将Phoneword应用程序扩展到包含第二个屏幕,该屏幕可以跟踪应用程序的拨打历史 Navigation   Xamarin.Form提供了一个内置的导航模型,用于管理一堆页面的导航和用户体验,这个模型实现了Page对象的后进先出(LIFO)堆栈,要从一个页面移动到另一个页面,应用程序将把一个新页面推到这个堆栈上,要返回到前一个页面,应用程序将从堆栈中弹出当前页面。
1024 0