当前位置: 首页 > article >正文

c# 动态lambda实现二级过滤(多种参数类型)

效果

调用方法

实体类(可以根据需求更换)

public class ToolStr50
{
    public bool isSelected { get; set; }

    public string toolStr1 { get; set; }
    public string toolStr2 { get; set; }
    public string toolStr3 { get; set; }
    public string toolStr4 { get; set; }
    public string toolStr5 { get; set; }
    public string toolStr6 { get; set; }
    public string toolStr7 { get; set; }
    public string toolStr8 { get; set; }
    public string toolStr9 { get; set; }
    public string toolStr10 { get; set; }

    public int toolInt1 { get; set; }
    public int toolInt2 { get; set; }
    public int toolInt3 { get; set; }
    public int toolInt4 { get; set; }
    public int toolInt5 { get; set; }
    public int toolInt6 { get; set; }
    public int toolInt7 { get; set; }
    public int toolInt8 { get; set; }
    public int toolInt9 { get; set; }
    public int toolInt10 { get; set; }
               
    public double toolDouble1 { get; set; }
    public double toolDouble2 { get; set; }
    public double toolDouble3 { get; set; }
    public double toolDouble4 { get; set; }
    public double toolDouble5 { get; set; }
    public double toolDouble6 { get; set; }
    public double toolDouble7 { get; set; }
    public double toolDouble8 { get; set; }
    public double toolDouble9 { get; set; }
    public double toolDouble10 { get; set; }

    public DateTime toolDate1 { get; set; }
    public DateTime toolDate2 { get; set; }
    public DateTime toolDate3 { get; set; }
    public DateTime toolDate4 { get; set; }
    public DateTime toolDate5 { get; set; }
    public DateTime toolDate6 { get; set; }
    public DateTime toolDate7 { get; set; }
    public DateTime toolDate8 { get; set; }
    public DateTime toolDate9 { get; set; }
    public DateTime toolDate10 { get; set; }
}

传入需要二级过滤的数据

 public void ShowSecondaryFiltration()
 {
     var columnMappings = new Dictionary<string, string>
         {
            { "采购日期", "toolStr26" },
             { "采购周期", "toolInt10" },
             { "采购回复交期", "toolStr31" },
             { "采购说明", "toolStr53" },
             { "生产订单号", "toolStr1" },
             { "来源单号", "toolStr2" },
             { "采购订单号", "toolStr3" },
             { "行号", "toolInt1" },
             { "料号", "toolStr4" },
             { "品名", "toolStr5" },
             { "规格描述", "toolStr6" },
             { "现存量", "toolInt2" },
             { "单位", "toolStr11" },
             { "采购数量(计量)", "toolInt3" },
             { "收货数量(计量)", "toolInt4" },
             { "已退货数(计量)", "toolInt5" },
             { "实际入库数(计量)", "toolInt6" },
             { "入库单号", "toolStr16" },
             { "已暂收数量(计量)", "toolInt7" },
             { "最后交货日期", "toolStr18" },
             { "逾期天数(负数未到期)", "toolInt8" },
             { "品质异常报告日期", "toolStr19" },
             { "品质问题描述", "toolStr20" },
             { "处理结论", "toolStr21" },
             { "未交数量(计量)", "toolInt9" },
             { "交货结案日期", "toolStr23" },
             { "请购日期", "toolStr24" },
             { "PMC交单日期", "toolStr25" },
             { "理论交期", "toolStr28" },
             { "要求交期", "toolStr29" },
             { "订单回传日期", "toolStr30" },
             { "色板_模板_图纸提供情况", "toolStr32" },
             { "异常反馈", "toolStr33" },
             { "预付款比例", "toolInt11" },
             { "预付款支付日期", "toolStr35" },
             { "尾款比例", "toolInt12" },
             { "尾款支付日期", "toolStr39" },
             { "采购员", "toolStr44" },
             { "请购制单人", "toolStr40" },
             { "供应商名称", "toolStr46" },
             { "请购单备注", "toolStr42" },
             { "采购单备注", "toolStr45" },
             { "可用量", "toolStr8" },
             { "含税单价", "toolDouble1" },
             { "含税金额", "toolDouble2" },
             { "采购到货日期", "toolStr37" },
             { "财务交单日期", "toolStr38" },
             { "请购人", "toolStr41" },
             { "采购制单人", "toolStr43" },
             { "采购订单结案状态", "toolStr48" },
             { "修改日期_请购", "toolStr50" },
             { "修改日期_采购", "toolStr51" },
             { "PMC要求交货日期", "toolStr52" }
         };
     var traceWindow = new TraceTableSecondaryFiltration(columnMappings, OdlIbo);

     traceWindow.QueryConditions = _queryConditions;

     if (traceWindow.ShowDialog() == true) // 检查对话框的结果
     {
         var filteredIbo = traceWindow.FilteredData;
         _queryConditions = traceWindow.QueryConditions;
         Ibo = filteredIbo;
         // 使用 filteredIbo 进行后续处理
     }
     if (_queryConditions.Count == 0)
     {
         SelectInfo();
     }
     //更新总条数和总金额
     InfoCount = "数据汇总:" + Ibo.Count.ToString() + "条";
     decimal total = Ibo.Sum(x => Convert.ToDecimal(x.toolStr10)); // 假设 TaxInclusiveSum 是 double 类型  
     total = decimal.Round(total, 4);//
     TaxinclusiveSum = "合计含税金额:" + total.ToString();

 }

窗体页面TraceTableSecondaryFiltration.xaml

<Window x:Class="GMWPF.Views.ModuleMenu.Purchase.PurchaseModle1.ChildWindow.TraceTableSecondaryFiltration"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:GMWPF.Views.ModuleMenu.Purchase.PurchaseModle1.ChildWindow"
        mc:Ignorable="d"
        Title="TraceTableSecondaryFiltration" Height="450" Width="800"
        WindowStartupLocation="CenterScreen">
    <Grid Margin="10" Name="myDynamicGrid">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <!-- 让表格占用剩余空间 -->
        </Grid.RowDefinitions>
 
        <TextBlock Text="字段名称" Margin="49,34,655,0" VerticalAlignment="Top" Grid.Row="0"/>
        <ComboBox Name="FieldNameComboBox" 
          Margin="25,5,640,0" 
          VerticalAlignment="Top" 
          ItemsSource="{Binding FieldNames}" 
          SelectedItem="{Binding SelectedFieldName, Mode=TwoWay}" 
          SelectionChanged="FieldNameComboBox_SelectionChanged"
          Grid.Row="1"/>
        <TextBlock Text="条件" Margin="227,34,495,0" VerticalAlignment="Top" Grid.Row="0"/>
        <ComboBox Name="ConditionComboBox" 
                  Margin="184,5,471,0" 
                  VerticalAlignment="Top" 
                  ItemsSource="{Binding Conditions}" 
                  SelectedItem="{Binding SelectedCondition}" 
                  Grid.Row="1"/>
 
        <TextBlock Text="条件值" Margin="402,34,320,0" VerticalAlignment="Top" Grid.Row="0"/>
        <ComboBox Name="ValueComboBox" 
                  Margin="357,5,275,0" 
                  VerticalAlignment="Top" 
                  ItemsSource="{Binding ConditionValues}" 
                  SelectedItem="{Binding SelectedConditionValue}" 
                  Grid.Row="1"/>
 
        <TextBlock Text="关系" Margin="564,34,168,0" VerticalAlignment="Top" Grid.Row="0"/>
        <ComboBox Name="RelationComboBox" 
                  Margin="532,5,154,0" 
                  VerticalAlignment="Top" 
                  ItemsSource="{Binding RelationValues}" 
                  SelectedItem="{Binding SelectedRelationValue}" 
                  Grid.Row="1"/>
 
        <Button Content="添加" Command="{Binding AddQueryConditionCommand}" 
                Margin="637,5,0,0" 
                HorizontalAlignment="Left" 
                VerticalAlignment="Top" 
                Height="27" 
                Grid.Row="1"/>
        <Button Content="查询" Command="{Binding QueryCommand}" 
                Margin="697,5,0,0" 
                HorizontalAlignment="Left" 
                VerticalAlignment="Top" 
                Height="27" 
                Grid.Row="1"/>
        <DataGrid Name="ConditionDataGrid" 
          Grid.Row="2" 
          Margin="10,10,10,0" 
          BorderThickness="1"
          Height="300"
          AutoGenerateColumns="False" 
          ItemsSource="{Binding QueryConditions}">
            <DataGrid.Columns>
                <DataGridTextColumn Width="200" Header="字段名称" Binding="{Binding FieldName}">
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="TextBlock">
                            <Setter Property="HorizontalAlignment" Value="Center"/>
                            <Setter Property="VerticalAlignment" Value="Center"/>
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                    <DataGridTextColumn.HeaderStyle>
                        <Style TargetType="DataGridColumnHeader">
                            <Setter Property="HorizontalContentAlignment" Value="Center"/>
                        </Style>
                    </DataGridTextColumn.HeaderStyle>
                </DataGridTextColumn>
 
                <DataGridTextColumn Width="100" Header="条件" Binding="{Binding Condition}">
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="TextBlock">
                            <Setter Property="HorizontalAlignment" Value="Center"/>
                            <Setter Property="VerticalAlignment" Value="Center"/>
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                    <DataGridTextColumn.HeaderStyle>
                        <Style TargetType="DataGridColumnHeader">
                            <Setter Property="HorizontalContentAlignment" Value="Center"/>
                        </Style>
                    </DataGridTextColumn.HeaderStyle>
                </DataGridTextColumn>
 
                <DataGridTextColumn Width="200" Header="条件值" Binding="{Binding ConditionValue}">
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="TextBlock">
                            <Setter Property="HorizontalAlignment" Value="Center"/>
                            <Setter Property="VerticalAlignment" Value="Center"/>
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                    <DataGridTextColumn.HeaderStyle>
                        <Style TargetType="DataGridColumnHeader">
                            <Setter Property="HorizontalContentAlignment" Value="Center"/>
                        </Style>
                    </DataGridTextColumn.HeaderStyle>
                </DataGridTextColumn>
 
                <DataGridTextColumn Width="100" Header="关系" Binding="{Binding RelationValue}">
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="TextBlock">
                            <Setter Property="HorizontalAlignment" Value="Center"/>
                            <Setter Property="VerticalAlignment" Value="Center"/>
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                    <DataGridTextColumn.HeaderStyle>
                        <Style TargetType="DataGridColumnHeader">
                            <Setter Property="HorizontalContentAlignment" Value="Center"/>
                        </Style>
                    </DataGridTextColumn.HeaderStyle>
                </DataGridTextColumn>
 
                <DataGridTemplateColumn Width="200" Header="操作">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button Content="删除" Width="80" 
                                Command="{Binding DataContext.DeleteConditionCommand, 
                                                 RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                                    CommandParameter="{Binding}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.HeaderStyle>
                        <Style TargetType="DataGridColumnHeader">
                            <Setter Property="HorizontalContentAlignment" Value="Center"/>
                        </Style>
                    </DataGridTemplateColumn.HeaderStyle>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
 
    </Grid>
</Window>

窗体实现类TraceTableSecondaryFiltration.xaml.cs

这里在进行数据对比时对数据进行了类型转换,因为string类型的对比会出现

“4”>“20”的情况

using CommunityToolkit.Mvvm.Input;
using SQLSugarDB.Model.Public;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Expression = System.Linq.Expressions.Expression;
namespace GMWPF.Views.ModuleMenu.Purchase.PurchaseModle1.ChildWindow
{
    public partial class TraceTableSecondaryFiltration : Window
    {
        public List<ToolStr50> FilteredData { get; private set; }


        private Dictionary<string, string> _columnMappings;//所有的列和对应Toolstr属性的映射关系
        private List<ToolStr50> _Ibo;//所有的数据

        private List<string> _fieldNames = new List<string>(); // 字段名
        public List<string> FieldNames
        {
            get { return _fieldNames; }
            set
            {
                _fieldNames = value;
            }
        }

        private string _selectedFieldName;
        public string SelectedFieldName
        {
            get { return _selectedFieldName; }
            set
            {
                _selectedFieldName = value;

            }
        }


        private ObservableCollection<string> _conditions = new ObservableCollection<string>(); // 条件
        public ObservableCollection<string> Conditions
        {
            get { return _conditions; }
            set
            {
                _conditions = value;
            }
        }

        private string _selectedCondition;
        public string SelectedCondition
        {
            get { return _selectedCondition; }
            set
            {
                _selectedCondition = value;
            }
        }


        private ObservableCollection<string> _conditionValues = new ObservableCollection<string>(); // 条件值
        public ObservableCollection<string> ConditionValues
        {
            get { return _conditionValues; }
            set
            {
                _conditions = value;

            }
        }

        private string _selectedConditionValue;
        public string SelectedConditionValue
        {
            get { return _selectedConditionValue; }
            set
            {
                _selectedConditionValue = value;
            }
        }


        private ObservableCollection<string> _relationValues = new ObservableCollection<string>(); // 关系
        public ObservableCollection<string> RelationValues
        {
            get { return _relationValues; }
            set
            {
                _relationValues = value;
            }
        }

        private string _selectedRelationValue;
        public string SelectedRelationValue
        {
            get { return _selectedRelationValue; }
            set
            {
                _selectedRelationValue = value;
            }
        }


        private ObservableCollection<SecondQueryCondition> _queryConditions = new ObservableCollection<SecondQueryCondition>();


        public ObservableCollection<SecondQueryCondition> QueryConditions
        {
            get => _queryConditions;
            set
            {
                _queryConditions = value;
            }

        }

        public TraceTableSecondaryFiltration(Dictionary<string, string> columnMappings, List<ToolStr50> Ibo)
        {
            _columnMappings = columnMappings;
            _Ibo = Ibo;
            InitializeComponent();
            DataContext = this; // 设置数据上下文为当前窗口
            //将columnMappings所有的key拿出来放进List<string> _fieldNames中
            _fieldNames = new List<string>(_columnMappings.Keys);

            Conditions.Add("大于");
            Conditions.Add("大于等于");
            Conditions.Add("小于");
            Conditions.Add("小于等于");
            Conditions.Add("等于");
            Conditions.Add("不等于");

            RelationValues.Add("并且");
            RelationValues.Add("或者");
            //设定个默认值
            SelectedRelationValue = "并且";
        }
        [RelayCommand]
        public void AddQueryCondition()
        {

            // 检查是否有空值或空字符串
            if (string.IsNullOrEmpty(_selectedFieldName) ||
                string.IsNullOrEmpty(_selectedCondition) ||
                string.IsNullOrEmpty(_selectedConditionValue) ||
                string.IsNullOrEmpty(_selectedRelationValue))
            {
                return; // 如果有空值,直接返回
            }

            // 创建并添加 SecondQueryCondition 对象到 QueryConditions 列表
            QueryConditions.Add(new SecondQueryCondition(QueryConditions.Count + 1, _selectedFieldName, _selectedCondition, _selectedConditionValue, _selectedRelationValue));
        }
        private void FieldNameComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ConditionValues.Clear();
            _columnMappings.TryGetValue(_selectedFieldName, out string property);

            if (_Ibo == null)
            {
                return;
            }

            foreach (var item in _Ibo)
            {
                string propertyValue = item.GetType().GetProperty(property)?.GetValue(item)?.ToString();

                if (!string.IsNullOrEmpty(propertyValue) && !ConditionValues.Contains(propertyValue))
                {
                    ConditionValues.Add(propertyValue);
                }
            }
        }

        [RelayCommand]
        public void DeleteCondition(SecondQueryCondition secondQueryCondition)
        {
            QueryConditions.Remove(secondQueryCondition);
        }
        [RelayCommand]
        public void Query()
        {
            var parameter = Expression.Parameter(typeof(ToolStr50), "p");
            Expression finalExpression = null;

            foreach (var queryCondition in QueryConditions)
            {
                if (_columnMappings.TryGetValue(queryCondition.FieldName, out string property))
                {
                    var member = Expression.Property(parameter, property);
                    var conditionValue = Expression.Constant(queryCondition.ConditionValue, typeof(string));
                    Expression comparison;

                    // 尝试解析为 int, double, DateTime
                    if (int.TryParse(queryCondition.ConditionValue, out int intValue))
                    {
                        var intMember = Expression.Convert(member, typeof(int));
                        var intConditionValue = Expression.Constant(intValue, typeof(int));

                        comparison = GetIntegerComparison(queryCondition.Condition, intMember, intConditionValue);
                    }
                    else if (double.TryParse(queryCondition.ConditionValue, out double doubleValue))
                    {
                        var doubleMember = Expression.Convert(member, typeof(double));
                        var doubleConditionValue = Expression.Constant(doubleValue, typeof(double));

                        comparison = GetDoubleComparison(queryCondition.Condition, doubleMember, doubleConditionValue);
                    }
                    //如果日期类型无法对比直接注释掉,按照string类型对比
                    //else if (DateTime.TryParse(queryCondition.ConditionValue, out DateTime dateTimeValue))
                    //{
                    //    var dateTimeMember = Expression.Convert(member, typeof(DateTime));
                    //    var dateTimeConditionValue = Expression.Constant(dateTimeValue, typeof(DateTime));

                    //    comparison = GetDateTimeComparison(queryCondition.Condition, dateTimeMember, dateTimeConditionValue);
                    //}
                    else
                    {
                        // 如果无法转换,继续使用字符串比较
                        comparison = GetStringComparison(queryCondition.Condition, member, conditionValue);
                    }

                    // 组合条件
                    if (finalExpression == null)
                    {
                        finalExpression = comparison;
                    }
                    else
                    {
                        if (queryCondition.RelationValue.Equals("并且"))
                        {
                            finalExpression = Expression.AndAlso(finalExpression, comparison); // 使用 AndAlso 组合条件
                        }
                        if (queryCondition.RelationValue.Equals("或者"))
                        {
                            finalExpression = Expression.Or(finalExpression, comparison); // 使用 Or 组合条件
                        }
                    }
                }
            }

            // 生成最终的 Lambda 表达式
            if (finalExpression != null)
            {
                var lambda = Expression.Lambda<Func<ToolStr50, bool>>(finalExpression, parameter);
                FilteredData = _Ibo.Where(lambda.Compile()).ToList();
                this.DialogResult = true; // 可选: 设置窗口的结果
                this.Close(); // 关闭窗口
            }
            else //没有查询条件查全部
            {
                FilteredData = _Ibo;
                this.DialogResult = true; // 可选: 设置窗口的结果
                this.Close(); // 关闭窗口
            }
        }

        private Expression GetIntegerComparison(string condition, Expression member, Expression conditionValue)
        {
            return condition switch
            {
                "大于" => Expression.GreaterThan(member, conditionValue),
                "大于等于" => Expression.GreaterThanOrEqual(member, conditionValue),
                "小于" => Expression.LessThan(member, conditionValue),
                "小于等于" => Expression.LessThanOrEqual(member, conditionValue),
                "等于" => Expression.Equal(member, conditionValue),
                "不等于" => Expression.NotEqual(member, conditionValue),
                _ => throw new NotSupportedException($"不支持的条件: {condition}")
            };
        }

        private Expression GetDoubleComparison(string condition, Expression member, Expression conditionValue)
        {
            return condition switch
            {
                "大于" => Expression.GreaterThan(member, conditionValue),
                "大于等于" => Expression.GreaterThanOrEqual(member, conditionValue),
                "小于" => Expression.LessThan(member, conditionValue),
                "小于等于" => Expression.LessThanOrEqual(member, conditionValue),
                "等于" => Expression.Equal(member, conditionValue),
                "不等于" => Expression.NotEqual(member, conditionValue),
                _ => throw new NotSupportedException($"不支持的条件: {condition}")
            };
        }

        private Expression GetDateTimeComparison(string condition, Expression member, Expression conditionValue)
        {
            return condition switch
            {
                "大于" => Expression.GreaterThan(member, conditionValue),
                "大于等于" => Expression.GreaterThanOrEqual(member, conditionValue),
                "小于" => Expression.LessThan(member, conditionValue),
                "小于等于" => Expression.LessThanOrEqual(member, conditionValue),
                "等于" => Expression.Equal(member, conditionValue),
                "不等于" => Expression.NotEqual(member, conditionValue),
                _ => throw new NotSupportedException($"不支持的条件: {condition}")
            };
        }

        private Expression GetStringComparison(string condition, Expression member, Expression conditionValue)
        {
            // 比较两个字符串时,我们需要使用 string.Compare 方法
            var compareMethod = typeof(string).GetMethod("Compare", new[] { typeof(string), typeof(string) });

            return condition switch
            {
                // 等于
                "等于" => Expression.Equal(member, conditionValue),

                // 不等于
                "不等于" => Expression.NotEqual(member, conditionValue),

                // 大于
                "大于" => Expression.GreaterThan(
                    Expression.Call(null, compareMethod, member, conditionValue),
                    Expression.Constant(0)
                ),

                // 小于
                "小于" => Expression.LessThan(
                    Expression.Call(null, compareMethod, member, conditionValue),
                    Expression.Constant(0)
                ),

                // 大于等于
                "大于等于" => Expression.GreaterThanOrEqual(
                    Expression.Call(null, compareMethod, member, conditionValue),
                    Expression.Constant(0)
                ),

                // 小于等于
                "小于等于" => Expression.LessThanOrEqual(
                    Expression.Call(null, compareMethod, member, conditionValue),
                    Expression.Constant(0)
                ),

                _ => throw new NotSupportedException($"不支持的条件: {condition}")
            };
        }

    }
}

动态生成的lambda表达式:


http://www.kler.cn/a/385243.html

相关文章:

  • 一:时序数据库-Influx应用
  • 深度学习笔记10-多分类
  • MyBatis几种SQL写法
  • 【机器学习】机器学习中用到的高等数学知识
  • LightGBM-GPU不能装在WSL,能装在windows上
  • 【Java SE语法】抽象类(abstract class)和接口(interface)有什么异同?
  • 『VUE』21. 组件注册(详细图文注释)
  • Kubernetes时代的APM部署革新:基于Webhook的Agent动态注入
  • docker镜像文件导出导入
  • GPU服务器厂家:AI 赋能科学研究的创新突破
  • 1.每日SQL----2024/11/7
  • 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-30
  • 为什么人工智能增强的威胁和法律不确定性成为风险主管最关心的问题
  • 5G智能对讲终端|北斗有源终端|北斗手持机|单兵|单北斗
  • Java | Leetcode Java题解之第543题二叉树的直径
  • 关于遥感影像BIL、BIP、BSQ你知道多少?给一个二进制文件你会读取嘛~
  • uniapp使用腾讯即时通讯IM(复制即可使用)
  • 小白初入Android_studio所遇到的坑以及怎么解决
  • Java I/O流面试之道
  • 【JavaScript】网络请求之Promise fetch Axios及异步处理
  • C++【string类,模拟实现string类】
  • [zotero]Ubuntu搭建WebDAV网盘
  • 二十三、Mysql8.0高可用集群架构实战
  • c++ 多态性
  • qt QErrorMessage详解
  • 利用API返回值实现商品信息自动化更新:技术与实践