【问题标题】:C# - Linq - Adding Comparison operators (==,>=,<=,!=) dynamically in linq expressionC# - Linq - 在 linq 表达式中动态添加比较运算符 (==,>=,<=,!=)
【发布时间】:2021-08-08 10:39:33
【问题描述】:

我正在处理一个场景,我想在 linq 表达式中动态应用比较运算符 (==,>=,。

例子-

相等:
var filterData = data.Where(x => x.Exam.Where(y => y.ExamId ==examId)).Select(e=>e);

大于或等于:
var filterData = data.Where(x => x.Exam.Where(y => y.ExamId >=examId)) .Select(e=>e);

小于或等于:
var filterData = data.Where(x => x.Exam.Where(y => y.ExamId examId)) .Select(e=>e)

不等于:
var filterData = data.Where(x => x.Exam.Where(y => y.ExamId !=examId)).Select(e=>e);

如何将所有这些逻辑组合在单个语句(查询)中,而不是为每个比较运算符编写单独的语句(查询)。

用户将比较运算符作为参数传递,并在此基础上以动态方式生成 linq where 子句查询....

提前谢谢...

【问题讨论】:

  • 我怀疑 switch 声明是您最初的最佳选择。
  • @mjwills - 我正在寻找一个不需要多次写入条件的解决方案
  • 或许你可以使用这个:stackoverflow.com/questions/1190062/…
  • 然后您必须从属性、运算符和变量构建表达式。有很多例子可以做到这一点。
  • 您确实需要添加类的相关部分。 Data.Exam 是对象还是列表?等

标签: c# linq lambda linq-to-entities


【解决方案1】:
  1. 你需要一个开关,你不能直接传递像== 这样的操作符。
string operand = "==";

Func<Exam, bool> filter = operand switch
{
   "==" => ex => ex.ExamId == examId,
   ">=" => ex => ex.ExamId >= examId,
   // etc
   _ => throw new InvalidOperationException()
};
  1. 您不能“链接”。像您所做的那样的语句,您将需要 SelectMany
var filterData = data
    .SelectMany(d => d.Exam)
    .Where(e => filter(e));

【讨论】:

  • 那么编写此查询的最佳方法是什么? var filterData = data.Where(x =&gt; x.Exam.Where(y =&gt; y.ExamId == examId)).Select(e=&gt;e);
【解决方案2】:

传递给 Where 扩展方法的东西是 Func&lt;TSource, bool&gt;,所以它已经参数化了。您只需要创建 4 个委托并让用户选择其中一个

using System;
using System.Linq;
using System.Collections.Generic;    
                    
public class Program
{
    class Exam {public int Id;}
    class MyEntity {public Exam Exam;}
    
    static Dictionary<string, Func<MyEntity, bool>> CreateComparers(int examId) {
        return new Dictionary<string, Func<MyEntity, bool>> {
         {"==", x => x.Exam.Id == examId},
         {">=", x => x.Exam.Id >= examId},
         {"<=", x => x.Exam.Id <= examId},
         {"!=", x => x.Exam.Id != examId}};
    }
    
    public static void Main()
    {
        string key;
        var examId = 2;
        var data = new [] {
            new MyEntity {Exam = new Exam {Id = 0}},
            new MyEntity {Exam = new Exam {Id = 1}},
            new MyEntity {Exam = new Exam {Id = 2}},
            new MyEntity {Exam = new Exam {Id = 3}},
            new MyEntity {Exam = new Exam {Id = 4}},
        };
        var comparers = CreateComparers(examId);
        do { 
            Console.WriteLine("Choose comparison: {0}", string.Join ("  ", comparers.Keys));
            key = Console.ReadLine();
        }
        while (!comparers.ContainsKey(key));
   
        var comparer = comparers[key];

        var filterData = data
            .Where(comparer.Invoke)
            .Select(e => e);    
    
        foreach(var e in filterData)
           Console.WriteLine(e.Exam.Id);
   }

}

【讨论】:

    猜你喜欢
    • 2010-11-13
    • 2021-09-29
    • 2018-11-30
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 2011-11-22
    相关资源
    最近更新 更多