微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Entity Framework Core 3.1.6的动态查询构建问题

如何解决Entity Framework Core 3.1.6的动态查询构建问题

我正在动态构建LINQ查询。我使用EF Core 3.1.6(用于sql Server)。

我使用谓词创建带有IQueryable子句的where()

EF Core能够转换以下谓词表达式,并且查询按预期工作:

{p => ((p.Address != null) AndAlso p.Address.Contains(Convert("6152 Fames Ro",String)))}

但是EF Core无法转换以下谓词表达式:

{p => (((p.FirstName != null) AndAlso p.FirstName.Contains(Convert("fred",String))) OrElse ((p.MiddleName != null) AndAlso p.MiddleName.Contains(Convert("fred",String))))}

它引发以下异常:

LINQ表达式'DbSet \ r \ n .Where(p => p.FirstName!= null && p.FirstName.Contains(“ fred”)|| p.MiddleName!= null && p.MiddleName.Contains( “ fred”))'无法翻译。以一种可以翻译的形式重写查询,或者通过插入对AsEnumerable(),AsAsyncEnumerable(),ToList()或ToListAsync()的调用来显式切换到客户端评估。有关更多信息,请参见https://go.microsoft.com/fwlink/?linkid=2101038

我调查了以下问题:

如异常消息中所建议,我尝试对最后的AsEnumerable()执行ToList()IQueryable等操作,但这没有用。我想这将排除客户评估问题。

我确定我做错了;不知道是什么。

有人可以帮忙吗?如果需要,我可以提供更多信息。

解决方法

我找到了解决问题的方法。

谓词应构造如下:

{p => (((p.FirstName != null) AndAlso p.FirstName.Contains(Convert("fred",String))) OrElse Invoke(p => ((p.MiddleName != null) AndAlso p.MiddleName.Contains(Convert("fred",String))),p))}

以上谓词工作正常。

要解决此问题,我做了2处更改:

  1. 由此转换了以下扩展方法:
    public static Expression<Func<T,bool>> Or<T>(this Expression<Func<T,bool>> expr1,Expression<Func<T,bool>> expr2)
        {
            return Expression.Lambda<Func<T,bool>>
                (Expression.OrElse(expr1.Body,expr2.Body),expr1.Parameters);
        }
    
    对此:
    public static Expression<Func<T,bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2,expr1.Parameters);
            return Expression.Lambda<Func<T,invokedExpr),expr1.Parameters);
        }
    
  2. 改变了方式,我由此构造了常量表达式:
    var member = Expression.Property(parameter,propertyInfo);
                var filterValueConstant = Expression.Convert(Expression.Constant(convertedValue),propertyType);
    
    对此:
    var underlyingTypeConstExpr = Expression.Constant(convertedValue);
                var filterValueConstant = Expression.Convert(underlyingTypeConstExpr,propertyType);
    

这解决了我的问题。但是我仍然不知道为什么旧谓词不起作用。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。