我的问题有点复杂,所以我用下面的例子简化了它。
假设我有一个简单的整数列表。我在函数中收到两个条件输入参数,它们告诉我如何过滤。像这样的东西:
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;
}
您可以使用
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.");
}
}
}