在动态linq表达式中定义数组

时间:2017-04-10 07:13:16

标签: c# .net dynamic-linq

如何在动态linq表达式字符串中定义一个数组,我可以将其传递给.Where(string)? 我已经尝试了{ "val a", "val b", "val c" },但这不起作用。

以下是我想要实现的一个例子:

public class Person
{
    String Name { get; set; }
    int Age { get; set; }
}

现在我想使用完全动态创建的动态linq表达式字符串来查询IQueryable<Person>,例如,针对预定义值列表查询Name。以下是有效的,但是当有很多值时很麻烦:

myQueryablePersons.Where("Name == \"John Doe\" || Name == \"Mr Smith\" || Name == \"CatWoman\");

我想做的是这样的事情:

myQueryablePersons.Where("{ \"John Doe\", \"Mr Smith\", \"CatWoman\" }.Contains(Name)");

我知道如何使用普通的C#或普通的Linq实现这一点,但我想通过仅使用传递给Where()的字符串来实现。这有可能吗?我已经在Stackoverflow和其他网站上搜索了其他答案,但找不到任何真正符合我特定问题的答案。

2 个答案:

答案 0 :(得分:0)

我认为动态linq不支持创建数组“inline”。你能做的就是把它作为一个论点:

var persons = new[]
{
    new Person { Name = "John Doe" }
};

var names = new[] { "John Doe", "Mr Smith" };
var res = persons.AsQueryable().Where("@0.Contains(Name)", names).ToArray();

答案 1 :(得分:0)

简短的回答:否

长答案:

我的代码片段正常工作

Int32List("40, 6, 27").Contains(40) == True

使用此黑客Call function in dynamic linq

public class Int32List : List<int>
{
    public Int32List(string arr) : base(arr.Split(',').Select(a => int.Parse(a.Trim())))
    {
    }
}

(我尝试使用params int [],但字符串解析器不喜欢这样)

public static class ExpressionHelper
{
    //https://stackoverflow.com/questions/18313362/call-function-in-dynamic-linq
    private static bool _utilsAdded = false;
    private static void AddUtilites()
    {
        if (_utilsAdded == true)
            return;

        _utilsAdded = true;
        var type = typeof(DynamicQueryable).Assembly.GetType("System.Linq.Dynamic.ExpressionParser");

        FieldInfo field = type.GetField("predefinedTypes", BindingFlags.Static | BindingFlags.NonPublic);

        Type[] predefinedTypes = (Type[])field.GetValue(null);

        Array.Resize(ref predefinedTypes, predefinedTypes.Length + 1);
        predefinedTypes[predefinedTypes.Length - 1] = typeof(Int32List); // Your type

        field.SetValue(null, predefinedTypes);
    }
}

只需在第一次动态Linq调用之前调用ExpressionHelper.AddUtilities(),因为它会缓存可访问的类型。

您的情况应该是

myQueryablePersons.Where("StringList(\"John Doe, Mr Smith, CatWoman\").Contains(Name)")

但是在此设置下,您的字符串不能包含任何逗号。 这是我不用叉子就可以使它工作的唯一方法

此页面也很有帮助:https://github.com/kahanu/System.Linq.Dynamic/wiki/Dynamic-Expressions#operators

如果您需要访问数组中的元素,请使用“ it”关键字

StringList(\"John Doe, Mr Smith, CatWoman\").Any(it == "John Doe") == True