【问题标题】:Define an array in a dynamic linq expression在动态 linq 表达式中定义数组
【发布时间】:2017-04-10 07:13:15
【问题描述】:

如何在动态 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 和其他网站上搜索了其他答案,但找不到任何真正适合我特定问题的答案。

【问题讨论】:

  • 请澄清您的具体问题或添加其他详细信息以准确突出您的需要。正如目前所写的那样,很难准确地说出你在问什么。请参阅“如何提问”页面以获得澄清此问题的帮助。
  • 分享你的代码,说明你的问题。举个例子,比如“这是输入,这是输出,但这是预期的输出”。
  • 告诉我们确切地你正在使用哪个动态 linq(有两三个不同的实现)
  • 你想让Where({ "val a", "val b", "val c" })做什么?请更具体地说明您想要实现的目标。

标签: c# .net dynamic-linq


【解决方案1】:

我认为动态 linq 不支持创建“内联”数组。您可以做的是将它作为参数传递:

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();

【讨论】:

  • 谢谢,但在我的用例中我不能这样做,因为查询必须是完全动态的,不幸的是......
  • @Slayer 运气好吗?
【解决方案2】:

简短回答:没有

长答案:

我让这个 sn-p 工作了

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);
    }
}

只需在第一次 Dynamic 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-22
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多