Home > Software design >  How can I convert string to linq lambda expression in C#
How can I convert string to linq lambda expression in C#

Time:06-02

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