Multiple Values Contains with Dynamic Linq

萝らか妹 提交于 2021-01-28 19:44:49

问题


How to use Multiple value with Contain in Dynamic Linq.

Expected With Normal Linq :

using System;
using System.Linq;
public class Simple {
  public static void Main() {
    string[] names = { "Burke", "Laptop", "Computer", 
                       "Mobile", "Ahemed", "Sania", 
                       "Kungada", "David","United","Sinshia" };
      string[] vars = {"i","a"};
      var query = names.Where(i=> vars.Any(j=>i.Contains(j))).ToList();

      Console.WriteLine(query.Count);
  }
}

Expected SQL

SELECT * FROM User WHERE (NAME LIKE '%a%'OR NAME LIKE '%b%')

Tried Dynamic Linq :

query = query.Where("new[]{\"a\",\"c\"}.Any(i=>i.Contains(it.ProductName))");

Returns Exception :

No property or field 'ProductName' exists in type 'String'

Dependicies :

  • .NET CORE 2.2
  • EntityFramework Core 2.2.6
  • System.Linq.Dynamic.Core 1.0.18 (https://github.com/StefH/System.Linq.Dynamic.Core)

回答1:


There are two issues with your "tried dynamic query":

  1. When translating to the dynamic query you have mixed the variable names, because i and j are too similar.

  2. it is ambigous as there are 2 lambdas and so it is parsed as a parameter of the innermost lambda.

Let's first rename i to p (for "product names") and j to s (for "search"):

var query = names.Where(p => vars.Any(s => p.Contains(s))).ToList();

Then you can directly transform this to a dynamic Linq expression:

// The type of vars needs to be IEnumerable<string> otherwise Dynamic Linq does not see .Any
IEnumerable<string> vars = new[] {"i", "a"};
var query2 = names.Where("p => @0.Any(s => p.Contains(s))", vars).ToList();

Then you can replace the argument of inner lambda (s) with it

var query3 = names.Where("p => @0.Any(p.Contains(it))", vars).ToList();

As you can see you mixed up the object and argument of Contains.

Then you can apply the expression the EF query. So usage of argument p becomes p.ProductName:

IEnumerable<string> vars = new[] {"i", "a"};
query = query.Where("p => @0.Any(p.ProductName.Contains(it))", vars).ToList();

Or like this:

IEnumerable<string> vars = new[] {"i", "a"};
query = query.Where("p => @0.Any(s => p.ProductName.Contains(s))", vars).ToList();


来源:https://stackoverflow.com/questions/57624006/multiple-values-contains-with-dynamic-linq

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!