Define an array in a dynamic linq expression

.net c# dynamic-linq

Question

How can I define an array inside of a dynamic linq expression string, that I can pass into .Where(string) ? I already tried { "val a", "val b", "val c" }, but this does not work.

Here's an example of what I want to achieve:

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

Now I want to query an IQueryable<Person> using a completely dynamically created dynamic linq expression string, where e.g. Name is queried against a list of predefined values. The following works, but is cumbersome when there are a lot of values:

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

What I'd like to do is something like this:

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

I know how this can achieved using plain C# or plain Linq, but I want to do it by only using the string passed into Where() . Is this possible at all? I already searched other answers on Stackoverflow and other sites, but could not find any answer that really fits my specific question.

1
0
4/10/2017 7:31:17 AM

Popular Answer

Short answer: no

Long answer:

I got this snippet working

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

Using this hack Call function in dynamic linq

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

(I tried params int[] but the string parser doesn't like that)

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

Just call ExpressionHelper.AddUtilities() before your first Dynamic Linq call because it caches the accessible types.

In your case it would be

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

But your strings cant contain any commas with this setup. This is the only way I was able to make it work without using a fork

Also this page is helpful: https://github.com/kahanu/System.Linq.Dynamic/wiki/Dynamic-Expressions#operators

If you need to access the element in the array use the "it" keyword

StringList(\"John Doe, Mr Smith, CatWoman\").Any(it == "John Doe") == True
0
4/19/2019 5:02:12 PM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow