1

I am using Microsoft's Dynamic Linq (System.Linq.Dynamic) library to generate some queries at run time. This has worked great for me, but for one specific scenario.

Simplified scenario - I am trying to query all claims which have some specific tags that the user has selected and whose Balance is greater than some number.

static void Main(string[] args)
    {
        var claims = new List<Claim>();
        claims.Add(new Claim { Balance = 100, Tags = new List<string> { "Blah", "Blah Blah" } });
        claims.Add(new Claim { Balance = 500, Tags = new List<string> { "Dummy Tag", "Dummy tag 1" } });

        // tags to be searched for
        var tags = new List<string> { "New", "Blah" };
        var parameters = new List<object>();
        parameters.Add(tags);

        var query = claims.AsQueryable().Where("Tags.Any(@0.Contains(outerIt)) AND Balance > 100", parameters.ToArray());
    }

public class Claim
{
    public decimal? Balance { get; set; }
    public List<string> Tags { get; set; }
}

This query throws an error:

An unhandled exception of type 'System.Linq.Dynamic.ParseException' occurred in System.Linq.Dynamic.dll Additional information: No property or field 'Balance' exists in type 'String'

Dynamic linq parser seems to try to find the Balance property on the Tag and not on the Claim object.

  • I have tried to play around with outerIt, innerIt, It keywords in Dynamic Linq but none of it seems to work.
  • Changing the sequence works, but that's not an option for me, since in the real application the filters, operators and patterns will be dynamic (configured by end user).
  • Boxing the conditions in brackets (), also doesn't help.
  • Workaround - create a simple contains condition for every Tag selected e.g. Tags.Contains("New") OR Tags.Contains("Blah") etc.. But in the real application it results in a really complex / bad query for each condition and kills the performance.

I might be missing something or this could be a bug in the library.

I would really appreciate if someone could help me with this.

14
  • where did you learn such syntax, any document links? Commented Apr 7, 2017 at 7:32
  • This was my starting point: weblogs.asp.net/scottgu/…. Then there were other SO question from where I got references: stackoverflow.com/questions/37740409/… Commented Apr 7, 2017 at 7:36
  • From what I understand, most of the keywords that works for Linq / EF should for dynamic linq with a bit of syntactic difference. Commented Apr 7, 2017 at 7:38
  • but in the doc links you provided, i did not see any syntax of @n to be a left value, it can only be a right value. Commented Apr 7, 2017 at 7:39
  • @n to the left converts it into a SQL IN(values) operator. stackoverflow.com/questions/15633066/… Commented Apr 7, 2017 at 7:44

2 Answers 2

1

Found a/the bug in ParseAggregate... The pushing of itouterIt and back doesn't work if there are multiple levels. The code supposes that the it and outerIt won't be changed by a third party before being reset (technically the code isn't reentrant). You can try with other variants of System.Linq.Dynamic (there are like two or three variants out of there). Probably some variants have already fixed it.

Or you can take the code from the linked site and recompile it inside your code (in the end the "original" System.Linq.Dynamic is a single cs file) and you can patch it like this:

Expression ParseAggregate(Expression instance, Type elementType, string methodName, int errorPos)
{
    // Change starts here
    var originalIt = it;
    var originalOuterIt = outerIt;
    // Change ends here

    outerIt = it;
    ParameterExpression innerIt = Expression.Parameter(elementType, elementType.Name);
    it = innerIt;
    Expression[] args = ParseArgumentList();

    // Change starts here
    it = originalIt;
    outerIt = originalOuterIt;
    // Change ends here

    MethodBase signature;
    if (FindMethod(typeof(IEnumerableSignatures), methodName, false, args, out signature) != 1)

I've already opened an Issue with the suggested bug fix in the github of the project.

Sign up to request clarification or add additional context in comments.

4 Comments

I'll patch the file with your fix and let you know if that solves it. Thanks a lot.
That works. Thanks man, you saved me weeks of toiling. I don't quite understand the nature of the fix in the whole context, so I am not sure what could be the impact of this fix. Would it make sense to log a defect on github repo, so that it is fixed in any upcoming releases?
@AmanvirSinghMundra 2 minutes ago I've made an update to my post: I've already opened an Issue with the suggested bug fix in the github of the project.
Oops sorry you already done that, missed the last sentence. Thanks again
0

This seems to be working correctly in my version: System.Linq.Dynamic.Core

See the test here: https://github.com/StefH/System.Linq.Dynamic.Core/blob/master/test/System.Linq.Dynamic.Core.Tests/ComplexTests.cs#L19

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.