多个值包含动态 Linq
Multiple Values Contains with Dynamic Linq
如何在 Dynamic Linq 中使用 Contain 的多值。
正常 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);
}
}
预计SQL
SELECT * FROM User WHERE (NAME LIKE '%a%'OR NAME LIKE '%b%')
尝试过动态 Linq:
query = query.Where("new[]{\"a\",\"c\"}.Any(i=>i.Contains(it.ProductName))");
Returns 异常:
No property or field 'ProductName' exists in type 'String'
依赖项:
- .NET 核心 2.2
- EntityFramework 核心 2.2.6
- System.Linq.Dynamic.Core 1.0.18
(https://github.com/StefH/System.Linq.Dynamic.Core)
您的 "tried dynamic query" 有两个问题:
在转换为动态查询时,您混合了变量名称,因为 i
和 j
太相似了。
it
不明确,因为有 2 个 lambda,所以它被解析为最里面的 lambda 的参数。
我们先将 i
重命名为 p
(对于 "product names"),将 j
重命名为 s
(对于 "search"):
var query = names.Where(p => vars.Any(s => p.Contains(s))).ToList();
然后你可以直接将其转换为动态 Linq 表达式:
// 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();
然后你可以用 it
替换内部 lambda(s) 的参数
var query3 = names.Where("p => @0.Any(p.Contains(it))", vars).ToList();
如您所见,您混淆了 Contains
的对象和参数。
然后就可以将表达式应用到EF查询中了。所以参数 p
的用法变为 p.ProductName
:
IEnumerable<string> vars = new[] {"i", "a"};
query = query.Where("p => @0.Any(p.ProductName.Contains(it))", vars).ToList();
或者像这样:
IEnumerable<string> vars = new[] {"i", "a"};
query = query.Where("p => @0.Any(s => p.ProductName.Contains(s))", vars).ToList();
如何在 Dynamic Linq 中使用 Contain 的多值。
正常 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);
}
}
预计SQL
SELECT * FROM User WHERE (NAME LIKE '%a%'OR NAME LIKE '%b%')
尝试过动态 Linq:
query = query.Where("new[]{\"a\",\"c\"}.Any(i=>i.Contains(it.ProductName))");
Returns 异常:
No property or field 'ProductName' exists in type 'String'
依赖项:
- .NET 核心 2.2
- EntityFramework 核心 2.2.6
- System.Linq.Dynamic.Core 1.0.18 (https://github.com/StefH/System.Linq.Dynamic.Core)
您的 "tried dynamic query" 有两个问题:
在转换为动态查询时,您混合了变量名称,因为
i
和j
太相似了。it
不明确,因为有 2 个 lambda,所以它被解析为最里面的 lambda 的参数。
我们先将 i
重命名为 p
(对于 "product names"),将 j
重命名为 s
(对于 "search"):
var query = names.Where(p => vars.Any(s => p.Contains(s))).ToList();
然后你可以直接将其转换为动态 Linq 表达式:
// 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();
然后你可以用 it
var query3 = names.Where("p => @0.Any(p.Contains(it))", vars).ToList();
如您所见,您混淆了 Contains
的对象和参数。
然后就可以将表达式应用到EF查询中了。所以参数 p
的用法变为 p.ProductName
:
IEnumerable<string> vars = new[] {"i", "a"};
query = query.Where("p => @0.Any(p.ProductName.Contains(it))", vars).ToList();
或者像这样:
IEnumerable<string> vars = new[] {"i", "a"};
query = query.Where("p => @0.Any(s => p.ProductName.Contains(s))", vars).ToList();