Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NET Core Npgsql.EntityFrameworkCore ILikeExpression_C#_.net Core_Entity Framework Core_Npgsql - Fatal编程技术网

C# .NET Core Npgsql.EntityFrameworkCore ILikeExpression

C# .NET Core Npgsql.EntityFrameworkCore ILikeExpression,c#,.net-core,entity-framework-core,npgsql,C#,.net Core,Entity Framework Core,Npgsql,我正在使用EntityFramework Core和Npgsql提供程序,执行ILIKE查询工作正常: var query = dbContext.countries .Where(w => (w.name != null && EF.Functions.ILike(w.name, $"{search}%") ); 查询

我正在使用EntityFramework Core和Npgsql提供程序,执行ILIKE查询工作正常:

var query = dbContext.countries
                      .Where(w => (w.name != null && 
                               EF.Functions.ILike(w.name, $"{search}%")
                       );
查询被翻译成PostgreSQL的ILIKE,到目前为止还不错

我还在基于注释构建动态LINQ-[Searchable]或[Orderable]模型中的属性-我正在尝试了解如何使用表达式和Lambda执行ILIKE。代码:

 // works, except it produces just LIKE which is case sensitive. Not enough.
 expr = Expression.Call(property, nameof(string.Contains), new Type[] { }, Expression.Constant(search));

 // does not work, ends with exception, see below
 expr = new Npgsql.EntityFrameworkCore.PostgreSQL.Query.Expressions.Internal.ILikeExpression(property, Expression.Constant(search_query));
有什么想法吗?谢谢

// Exception

Application started. Press Ctrl+C to shut down.
fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HLGC19DMS3OI", Request id "0HLGC19DMS3OI:00000001": An unhandled exception was thrown by the application.
System.ArgumentException: must be reducible node
   at System.Linq.Expressions.Expression.ReduceAndCheck()
   at System.Linq.Expressions.Expression.ReduceExtensions()
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExtensionExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteLogicalBinaryExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteLogicalBinaryExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteLogicalBinaryExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteLogicalBinaryExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteLogicalBinaryExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpressionFreeTemps(Expression expression, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.Rewrite[T](Expression`1 lambda)
   at System.Linq.Expressions.Expression`1.Accept(StackSpiller spiller)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteLambdaExpression(Expression expr)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.Add(Expression expression)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.AddArguments(IArgumentProvider expressions)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteMethodCallExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.Add(Expression expression)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.AddArguments(IArgumentProvider expressions)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteMethodCallExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpressionFreeTemps(Expression expression, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.Rewrite[T](Expression`1 lambda)
   at System.Linq.Expressions.Expression`1.Accept(StackSpiller spiller)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteLambdaExpression(Expression expr)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.Add(Expression expression)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.AddArguments(IArgumentProvider expressions)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteMethodCallExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.Add(Expression expression)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.AddArguments(IArgumentProvider expressions)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteMethodCallExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpressionFreeTemps(Expression expression, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.Rewrite[T](Expression`1 lambda)
   at System.Linq.Expressions.Expression`1.Accept(StackSpiller spiller)
   at System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda)
   at System.Linq.Expressions.Expression`1.Compile(Boolean preferInterpretation)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateExecutorLambda[TResults]()
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateAsyncQueryExecutor[TResult](QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken
cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.CountAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
解决方法:

var _regex = typeof(System.Text.RegularExpressions.Regex).GetMethod("IsMatch", 
                                BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
                                null, 
                                new[] { 
                                    typeof(string),  
                                    typeof(string),
                                    typeof(System.Text.RegularExpressions.RegexOptions)
                                },
                                null
                                );

                        _expr = Expression.Call(_regex, property, Expression.Constant(search, typeof(string)), Expression.Constant(System.Text.RegularExpressions.RegexOptions.IgnoreCase));
编辑

工作代码:

var _ILike = typeof(NpgsqlDbFunctionsExtensions).GetMethod("ILike", 
                                BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
                                null, 
                                new[] { 
                                    typeof(Microsoft.EntityFrameworkCore.DbFunctions),  
                                    typeof(string),  
                                    typeof(string) 
                                },
                                null
                                );

_expr = Expression.Call(
                    _ILike, 
                    Expression.Constant(null, typeof(DbFunctions)), 
                    property, 
                    Expression.Constant(search, typeof(string)));

您需要发出相当于
EF.Functions.ILike(string,string)
调用的表达式

ILike
是一种静态扩展方法,定义为

public static class NpgsqlDbFunctionsExtensions
{
    public static bool ILike(this DbFunctions _, string matchExpression, string pattern);
}
函数
EF
类的静态属性

public static class EF
{
    public static DbFunctions Functions { get; }
}
因此,您寻求的表达方式如下:

expr = Expression.Call(
    typeof(NpgsqlDbFunctionsExtensions), 
    nameof(NpgsqlDbFunctionsExtensions.ILike),
    Type.EmptyTypes,
    Expression.Property(null, typeof(EF), nameof(EF.Functions)),
    property,
    Expression.Constant(search)
);
这(T类)适用于:

公共静态表达式GetCriteriaWhere(字符串字段名、对象字段值)
{
PropertyInfo prop=typeof(T).GetProperty(fieldName);
var参数=表达式参数(typeof(T));
var expressionParameter=GetMemberExpression(参数,字段名);
var_ILike=typeof(NpgsqlDbFunctionsExtensions).GetMethod(“ILike”,
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
无效的
新[]{
typeof(Microsoft.EntityFrameworkCore.DbFunctions),
类型(字符串),
类型(字符串)
},
无效的
);
var bodyLike=Expression.Call(_ILike,Expression.Constant(null,typeof(DbFunctions)),expressionParameter,Expression.Constant(“%”+fieldValue+“%”,typeof(string));
返回表达式.Lambda(bodyLike,parameter);
}

我在GitHub上也发现了这个问题,我也遇到了同样的问题。我不明白的是如何使用
Expression.Call()
expr
变量。linq查询中是否包含某种形式的
dbContext.countries.Where(q=>expr(q))
?@BarrettGay您需要从中创建和使用lambda表达式。e、 你会有一些类似于
var-param=Expression.Parameter(typeof(Country,“c”);var-property=Expression.property(param,string_-property_-name);var-expr=Expression.Call(…);var-predicate=Expression.Lambda(expr,param);
然后
var-query=dbContext.Countries.Where(predicate);
public static Expression<Func<T, bool>> GetCriteriaWhere<T>(string fieldName,  object fieldValue)
{
            PropertyInfo prop = typeof(T).GetProperty(fieldName);

            var parameter = Expression.Parameter(typeof(T));
            var expressionParameter = GetMemberExpression<T>(parameter, fieldName);

            var _ILike = typeof(NpgsqlDbFunctionsExtensions).GetMethod("ILike",
                BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new[] {
                                    typeof(Microsoft.EntityFrameworkCore.DbFunctions),
                                    typeof(string),
                                    typeof(string)
                },
                null
                );


            var bodyLike = Expression.Call(_ILike, Expression.Constant(null, typeof(DbFunctions)), expressionParameter, Expression.Constant("%" + fieldValue + "%", typeof(string)));

            return Expression.Lambda<Func<T, bool>>(bodyLike, parameter);
}