如何根据输入参数条件动态创建“OR”LINQ查询

问题描述 投票:0回答:1

我的问题有点复杂,所以我用下面的例子简化了它。

假设我有一个简单的整数列表。我在函数中收到两个条件输入参数,它们告诉我如何过滤。像这样的东西:

 public class input{
       public string operation = "less than";//can be <=, >=, !=, ==,<. >, etc. 
       public integer filter = 9;
}

我想根据传入的条件进行动态过滤,但我需要将其作为“OR”子句。

如何动态创建 linq 查询,而不需要像这样对每个组合进行硬编码:

/*
input one = { operation = "less than" , filter = 9 }
input two = { operation = "equal to", filter =10 }
arraytoFilter { 1,2,3,4,5,6,7,8,9,10,11,12 }
*/
public int[] myFilter(input one, input two, int[] arraytoFilter){

 if (one.operation == "less than" && two.operation == "equal to"){

    return arraytoFilter.Where(x => x < one.filter || x == two.filter)

   }

    if (one.operation == "less than or equal to" && two.operation == "greater than"){

    return arraytoFilter.Where(x => x <= one.filter || x > two.filter)

   }
 /// rest of all combinations (how do I avoid doing this???)
    return arrayToFilter;
}
c# asp.net linq linq-to-entities
1个回答
0
投票

您可以使用

System.Linq.Dynamic.Core
包来编写动态 LINQ 查询。以下程序已使用 1.3.5 版本进行测试:

using System.Linq.Dynamic.Core;

class Program
{
    public class input
    {
        public string? operation { get; set; }
        public int filter { get; set; }
    }

    static void Main()
    {
        int[] arrayToFilter = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };

        input one = new()
        {
            operation = "less than",
            filter = 9
        };

        input two = new()
        {
            operation = "equal to",
            filter = 10
        };

        var filteredArray = myFilter(one, two, arrayToFilter);

        foreach (var number in filteredArray)
        {
            Console.WriteLine(number);
        }
    }

    static int[] myFilter(input one, input two, int[] arrayToFilter)
    {
        var firstSymbol = ConvertOperationToSymbol(one.operation);
        var secondSymbol = ConvertOperationToSymbol(two.operation);

        string dynamicQuery = $"it {firstSymbol} {one.filter} || it {secondSymbol} {two.filter}";

        return arrayToFilter.AsQueryable().Where(dynamicQuery).ToArray();
    }

    static string ConvertOperationToSymbol(string? operation)
    {
        switch (operation)
        {
            case "less than":
                return "<";
            case "less than or equal to":
                return "<=";
            case "greater than":
                return ">";
            case "greater than or equal to":
                return ">=";
            case "equal to":
                return "==";
            case "not equal to":
                return "!=";
            default:
                throw new ArgumentException("Invalid operation phrase.");
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.