首页 > 其他分享 >linq 高级 规约

linq 高级 规约

时间:2024-08-18 17:16:58浏览次数:10  
标签:return string 规约 高级 linq name Expression public LinqExpressionLearn

LinqExpressionLearn\Linq\ParameterRebinder.cs


using System.Linq.Expressions;

/// <summary>
/// 表达式参数
/// </summary>
public class ParameterRebinder : ExpressionVisitor
{
    /// <summary>
    /// 参数字典
    /// </summary>
    private readonly Dictionary<ParameterExpression, ParameterExpression> map;

    public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
    {
        this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
    }

    /// <summary>
    /// 参数替换
    /// </summary>
    /// <param name="map"></param>
    /// <param name="exp"></param>
    /// <returns></returns>
    public static Expression ReplaceParameters(
        Dictionary<ParameterExpression, ParameterExpression> map,
        Expression exp
    )
    {
        return new ParameterRebinder(map).Visit(exp);
    }

    /// <summary>
    /// 表达式转换
    /// </summary>
    /// <param name="p"></param>
    /// <returns></returns>
    protected override Expression VisitParameter(ParameterExpression p)
    {
        if (map.TryGetValue(p, out ParameterExpression replacement))
        {
            p = replacement;
        }
        return base.VisitParameter(p);
    }
}

LinqExpressionLearn\Linq\PredicateBuilder.cs


using System.Linq.Expressions;

/// <summary>
/// Linq动态拼接
/// </summary>
public static class PredicateBuilder
{
    /// <summary>
    /// True表达式
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public static Expression<Func<T, bool>> True<T>()
    {
        return f => true;
    }

    /// <summary>
    /// False表达式
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public static Expression<Func<T, bool>> False<T>()
    {
        return f => false;
    }

    /// <summary>
    /// 表达式拼接
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="first"></param>
    /// <param name="second"></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);

        // 将第二个lambda表达式中的参数替换为第一个lambda中的参数
        var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);

        // 将lambda表达式体的组合应用于第一个表达式中的参数
        return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
    }

    /// <summary>
    /// 表达式And拼接
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="first"></param>
    /// <param name="second"></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.And);
    }

    /// <summary>
    /// 表达式AndAlso拼接
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="first"></param>
    /// <param name="second"></param>
    /// <returns></returns>
    public static Expression<Func<T, bool>> AndAlso<T>(
        this Expression<Func<T, bool>> first,
        Expression<Func<T, bool>> second
    )
    {
        return first.Compose(second, Expression.AndAlso);
    }

    /// <summary>
    /// 表达式Or拼接
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="first"></param>
    /// <param name="second"></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.Or);
    }

    /// <summary>
    /// 表达式OrElse拼接
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="first"></param>
    /// <param name="second"></param>
    /// <returns></returns>
    public static Expression<Func<T, bool>> OrElse<T>(
        this Expression<Func<T, bool>> first,
        Expression<Func<T, bool>> second
    )
    {
        return first.Compose(second, Expression.OrElse);
    }
}

LinqExpressionLearn\EleTodo.cs


/// <summary>
/// todo状态
/// </summary>
public enum TodoStatus
{
    /// <summary>
    /// 未做
    /// </summary>
    Pending,

    /// <summary>
    /// 已做
    /// </summary>
    Completed,
}

public class EleTodo
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Remark { get; set; }
    public TodoStatus Status { get; set; }
}

LinqExpressionLearn\global.json


{
  "sdk": {
    "version": "8.0.300"
  }
}

LinqExpressionLearn\ISpecification.cs


using System.Linq.Expressions;

/// <summary>
/// 规约接口
/// </summary>
/// <typeparam name="T"></typeparam>
public interface ISpecification<T>
{
    /// <summary>
    /// 用来验证模型是否满足规约要求
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    bool IsSatisfiedBy(T obj);

    /// <summary>
    /// 获取表示当前规约的LINQ表达式。
    /// </summary>
    /// <returns></returns>
    Expression<Func<T, bool>> ToExpression();
}

LinqExpressionLearn\LinqExpressionLearn.csproj


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

LinqExpressionLearn\LinqExpressionLearn.sln

LinqExpressionLearn\Program.cs


class Program
{
    static void Main(string[] args)
    {
        // 创建一些示例待办事项
        var todos = new List<EleTodo>
        {
            new EleTodo { Id = Guid.NewGuid(), Name = "买牛奶", Remark = "超市", Status = TodoStatus.Pending },
            new EleTodo { Id = Guid.NewGuid(), Name = "买面包", Remark = "便利店", Status = TodoStatus.Completed },
            new EleTodo { Id = Guid.NewGuid(), Name = "买鸡蛋", Remark = "超市", Status = TodoStatus.Pending },
            new EleTodo { Id = Guid.NewGuid(), Name = "买面包", Remark = "超市", Status = TodoStatus.Pending }
        };

        // 创建 TodoAppService 实例
        var todoAppService = new TodoAppService(todos.AsEnumerable());

        // 使用规约来过滤待办事项
        var filteredTodos = todoAppService.FilterTodos("买面包");

        // 输出过滤后的待办事项
        foreach (var todo in filteredTodos)
        {
            Console.WriteLine($"ID: {todo.Id}, Name: {todo.Name}, Remark: {todo.Remark}, Status: {todo.Status}");
        }
    }
}





LinqExpressionLearn\Specification.cs


using System.Linq.Expressions;


/// <summary>
/// 规约
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class Specification<T> : ISpecification<T>
{
    /// <summary>
    /// 用来验证模型是否满足规约要求
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public virtual bool IsSatisfiedBy(T obj)
    {
        return ToExpression().Compile()(obj);
    }

    /// <summary>
    /// 获取表示当前规范的LINQ表达式
    /// </summary>
    /// <returns></returns>
    public abstract Expression<Func<T, bool>> ToExpression();

    /// <summary>
    /// 将规范隐式转换为表达式。
    /// </summary>
    /// <param name="specification"></param>
    public static implicit operator Expression<Func<T, bool>>(Specification<T> specification)
    {
        return specification.ToExpression();
    }
}

LinqExpressionLearn\TodoAppService.cs



public class TodoAppService
{
    private readonly IEnumerable<EleTodo> _todos;

    public TodoAppService(IEnumerable<EleTodo> todos)
    {
        _todos = todos;
    }

    public IEnumerable<EleTodo> FilterTodos(string? name, string? remark = null, TodoStatus? status =null)
    {
        var specification = new TodoNameRemarkStatusFiltereSpecification(name, remark, status);
        var filteredTodos = _todos.Where(specification.ToExpression().Compile()).ToList();
        return filteredTodos;
    }
}


LinqExpressionLearn\TodoNameRemarkStatusFiltereSpecification.cs


using System.Linq.Expressions;



public class TodoNameRemarkStatusFiltereSpecification : Specification<EleTodo>
{
    private string? _name;
    private string? _remark;
    private TodoStatus? _status;

    public TodoNameRemarkStatusFiltereSpecification(string? name, string? remark, TodoStatus? status)
    {
        _name = name;
        _remark = remark;
        _status = status;
    }

    public override Expression<Func<EleTodo, bool>> ToExpression()
    {
        Expression<Func<EleTodo, bool>> filter = PredicateBuilder.True<EleTodo>();

        if (!string.IsNullOrEmpty(_name))
        {
            filter = filter.Compose(x => x.Name.Contains(_name), Expression.AndAlso);
        }

        if (!string.IsNullOrEmpty(_name) && !string.IsNullOrEmpty(_remark))
        {
            filter = filter.Compose(x => x.Name.Contains(_name) && (x.Remark == null ? false : x.Remark.Contains(_remark)), Expression.AndAlso);
        }

        if (!string.IsNullOrEmpty(_name) && !string.IsNullOrEmpty(_remark) && _status != null)
        {
            filter = filter.Compose(
                x => x.Name.Contains(_name) && (x.Remark == null ? false : x.Remark.Contains(_remark)) && x.Status == _status,
                Expression.AndAlso
            );
        }

        return filter;
    }
}

标签:return,string,规约,高级,linq,name,Expression,public,LinqExpressionLearn
From: https://www.cnblogs.com/zhuoss/p/18365816

相关文章

  • day23-测试自动化之Appium的滑动和拖拽事件、高级手势ActionChains、手机操作API
    目录一、滑动和拖拽事件    1.1.应用场景    1.2.swipe滑动事件    1.3.scroll滑动事件    1.4.drag_and_drop拖拽事件    1.5.滑动和拖拽事件的选择二、高级手势ActionChains    2.1.应用场景    2.2.使用......
  • 高级java每日一道面试题-2024年8月16日-设计模式篇-解释装饰者模式和代理模式的区别?
    如果有遗漏,评论区告诉我进行补充面试官:解释装饰者模式和代理模式的区别?我回答:在Java中,装饰者模式(DecoratorPattern)和代理模式(ProxyPattern)都是常用的设计模式,它们在结构上看起来有些相似,但实际上它们的目的、应用场景和实现方式存在明显的区别。下面详细解释这两种......
  • Java基础——面向对象编程高级(常见关键字)
    package:用于声明一个类或接口所属的包(即命名空间)语法格式:package顶层包名.子包名OrderController类属于包com.hxzs.order.controller一个源文件只能有一个声明包的package语句package语句作为Java源文件的第一条语句出现。若缺省该语句,则指定为无名包。包名,属于标识符,满......
  • Git 高级用法详解
    文章目录Git高级用法详解标签管理1.1创建标签1.2查看标签1.3推送标签变基操作(Rebase)2.1变基的基本操作2.2处理变基时的冲突2.3交互变基解决冲突3.1合并冲突3.2变基冲突撤销更改4.1撤销未提交的更改4.2撤回已提交的更改4.3重置分支与远程仓库交互5.1添加......
  • 嵌入式学习 20(Linux高级编程——文件——misc)
     文件操作相关函数一、symlink函数intsymlink(constchar*oldpath,constchar*newpath);功能:创建一个指向oldpath文件的新的符号链接(软链接)文件。参数:•oldpath:被链接指向的原始文件的路径。•newpath:新创建的符号链接文件的路径。返回值:•成功时,返回0。......
  • linq快速动态获取数据库表字段名称、类型、数据
     varbj="Bj";             varpbj=typeof(Xs_xx).GetProperty(bj);//获得班级属性      /*      varcxbj=fromaainsjklj.Xs_xx            lety=(string)pbj.GetValue(aa,null)//linq......
  • 高级java每日一道面试题-2024年8月15日-设计模式篇-设计模式与面向对象原则的关系是什
    如果有遗漏,评论区告诉我进行补充面试官:设计模式与面向对象原则的关系是什么?我回答:在设计模式与面向对象原则的关系中,两者紧密相连且相互促进。面向对象的原则为设计模式的形成提供了理论基础和指导思想,而设计模式则是这些原则在特定问题域中的具体实践和实现方式。下......
  • day04(C高级)编译工具
    编译工具一.gcc编译工具预处理:#开头内容,展开头文件,替换宏定义,不会进行语法检查。gcc-Exx.c-oxx.i编译:检查语法错误,词法错误,将.i文件转换成.s汇编文件。gcc-Sxx.i-oxx.s汇编:将汇编文件转换成二进制文件(不可执行)gcc-cxx.s-oxx.o链接:链接库文件,将不可执......
  • ofcommon.dll故障深度探索:Office组件恢复的高级策略揭秘
    解决ofcommon.dll丢失的问题,采取以下专业步骤可以帮助您恢复Office组件的正常运作:1.系统文件检查:•以管理员身份运行命令提示符,输入sfc/scannow并回车。这将扫描并修复系统文件,包括可能缺失的ofcommon.dll。2.Office修复:•打开“控制面板”>“程序”>“程序和功......
  • 谷歌的高级指令有哪些
    今天会分享一些组合用法,这样就能节省许多时间可以放在跟进客户上面(本文只介绍谷歌的搜索指令,并无推广)partone谷歌常用的搜索引擎指令:1、Inurl,在网址中2、Intext,在网页内容中3、Site,在网站中01在网址中inurl在网址中 •使用inurl在网址中• 当我们用inurl......