I want to use string predicate instead of lambda code.
Here is list of dictionary:
void GenerateData()
{
DataDictionary = new List<Dictionary<string, string>>()
{
new Dictionary<string, string>()
{
{"a","1-1" },
{"b","1-2" }
},
new Dictionary<string, string>()
{
{"a","1-3" },
{"b","1-4" }
}
};
}
And find "1-1" from "a"
var data = DataDictionary.AsQueryable();
var result = data.Where(d => d["a"] == "1-1");
Can i convert d => d["a"] == "1-1" to string context? like "d => d[\"a\"] == \"1-1\""
Finally, I want use like this.
ProcessContext("a", "==\"1-1\"")
ProcessContext("a", "!=\"1-1\"")
void ProcessContext(string Field, string Context)
{
string predicate = $"d => d[\"{Field}\"] {Context}"
var result = data.Where(predicate);
}
Can someone help me? Thank you very much.
Update
I tried Orace's link How to convert a String to its equivalent LINQ Expression Tree?
It looks perfect solution. But I got an error. I will try to solve.
//Prev - It works
var result1 = data.Where(d => d["a"] == "1-1");
//Use Dynamic linq - 'Syntax error'
var result2 = data.Where("d => d[\"a\"] == \"1-1\"");
CodePudding user response:
It is possible to create string predicate with Dynamic Linq. Unfortunately, I am not familiar with it enough to tell how to iterate over a nested dictionary, so I use combined approach of a simple predicate $"Key == @0 && Value == @1"
and foreach
loop. You might want to learn more about this nuget package to get rid of foreach
loop.
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
namespace DynamicLinqDemo
{
internal class Program
{
static void Main(string[] args)
{
var item = GetDictionaryItem();
}
public static Dictionary<string, string> GetDictionaryItem()
{
var dict = new List<Dictionary<string, string>>()
{
new Dictionary<string, string>()
{
{"a","1-1" },
{"b","1-2" }
},
new Dictionary<string, string>()
{
{"a","1-3" },
{"b","1-4" }
}
};
var Field = "a";
var Context = "1-1";
string predicate = $"Key == @0 && Value == @1";
foreach (var item in dict)
{
var result = item.AsQueryable().Where(predicate, Field, Context).ToList();
if (result.Count > 0)
return item;
}
return null;
}
}
}
CodePudding user response:
ProcessContext(string Field, string Context)
{
Func<Dictionary<string, string>, bool> p1 = d => d.ContainsKey(Field);
Func<Dictionary<string, string>, bool> p2 = d => d[Field] == Context;
Func<Dictionary<string, string>, bool> p3 = d => p1(d) && p2(d);
var result = data.Where(p3);
}