How can I add a specific dictionary entry to a Linq Expression?

c# dynamic-linq linq linq-expressions

Question

I'm making use of the dynamic-linq-query-builder library and am attempting to generate an executable Linq query from a JSON representation of the query. I don't believe that this library supports Dictionaries as it stands, so I am looking to add this functionality.

My JSON looks like this:

{
  "condition": "AND",
  "rules": [
    {
      "id": "Field_1",
      "field": "Data[\"Field_1\"].StringValue",
      "type": "string",
      "input": "text",
      "operator": "equal",
      "value": "test"
    }
  ],
  "valid": true
}

and I'm trying to generate a Linq query like this:

.Where(p => p.Data["Field_1"].StringValue == "test")

I'm really struggling with how to generate an System.Linq.Expressions.Expression which represents this, effectively hard-coded, dictionary item (the Data["Field_1"]) part of the tree.

I've read lots of articles, and looked at this StackOverflow question how-do-i-access-a-dictionary-item-using-linq-expressions but the solution is still evading me.

Can anyone point me in the right direction? The problem is manifesting in the BuildNestedExpression() method of this class.

Thanks in advance.

Update 13/12/19

I'm making some progress with this, but feel like I'm rapidly loosing my sanity. As previously mentioned, the problem manifests in the BuildNestedExpression() method, which currently does not support dictionary properties. I'm trying to add support for this.

I appreciate my code could be much improved (just trying to get it working initially), but my changes are in GitHub here

I've made a change to break out of the BuildNestedExpression() if I find a Dictionary into my new method BuildElementAccessExpression(). In here I'm simply trying to add any dictionary entries to the expression being built up for a property. I'm getting very confused in the process though (as you can probably tell by the commented out code).

I've added a quick unit test to illustrate the problem (Dictionary_Test).

I'll refrain from posting huge chunks of code on here since it's available in GitHub. Any help would be really great, don't think I'm going to solve this one on my own.

1
0
12/13/2019 3:15:09 PM

Accepted Answer

I got there in the end with this problem. The process hurt my head a little, but the working code snippet to create the expression can be found below.

Hopefully this will save someone some time in the future.

Thanks for all your help @NetMage.

var propertyInfo = expression.Type.GetProperty("Data");
var propertyExpression = Expression.Property(expression, propertyInfo);

var dictionaryKeyValue = "dictionaryEntryKey";
var dictionaryKeyConst = Expression.Constant(dictionaryKeyValue);

var dictionary = propertyType.GetInterface("IDictionary`2");
PropertyInfo indexerProperty = dictionary.GetProperty("Item");

var indexExpression = Expression.MakeIndex(propertyExpression, indexerProperty, new[] { dictionaryKeyConst });

0
1/2/2020 12:56:42 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