实体框架在执行 lambda 表达式时抛出错误

Posted

技术标签:

【中文标题】实体框架在执行 lambda 表达式时抛出错误【英文标题】:Entity Framework throws an error when executing a lambda expression 【发布时间】:2019-01-19 21:32:06 【问题描述】:

我有这段代码用于从数据库中获取和过滤产品结果:

if (userParams.MinPrice > 0 && userParams.MaxPrice != 999999999) 

    products = products.Where(p => (p.Price >= userParams.MinPrice) && 
                                   (p.Price <= userParams.MaxPrice));

仅提供userParams.MinPrice 时执行成功,但提供userParams.MaxPrice 时执行失败。

我得到的错误是这样的。

执行请求时发生未处理的异常。

System.InvalidOperationException:尝试评估 LINQ 查询参数表达式时引发异常。要显示更多信息,请在覆盖 DbContext.OnConfiguring 时调用 EnableSensitiveDataLogging()。

System.NullReferenceException:对象引用未设置为实例 的一个对象。

在 lambda_method(闭包) 在 Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.Evaluate(表达式表达式,字符串和参数名称)。

有人知道这个问题的解决方案吗?请帮忙

【问题讨论】:

最高价格为空。 if (userParams.MinPrice != null && userParams.MinPrice > 0 && userParams.MaxPrice != null && userParams.MaxPrice != 999999999) MaxPrice 不为空,因为如果用户不提供自己的值,它的默认值为 999999999。 设置为默认值后,您必须将其设置为空。默认值不显示。 我已经调试,单步执行并确认它在传递给 where 子句时不为空。 【参考方案1】:

这很简单,你的错误解释了它。 userParams.MaxPrice 为空。所以你需要给它添加空检查。一种简单的方法是将查询更改为:

if (userParams.MinPrice > 0 && userParams.MaxPrice != null && userParams.MaxPrice != 999999999) 

    products = products.Where(p => (p.Price >= userParams.MinPrice) && 
                                   (p.Price <= userParams.MaxPrice));

虽然根据您的逻辑,您可能需要稍微改变一下。关键是不要假设一个属性有一个值,如果它可以为空,那么你需要先验证它不是空的,然后检查它。

还应该补充一点,假设这是一个可为空的 int 或类似的东西,理论上你可以做 userParams.MaxPrice.GetValueOrDefault() != 999999999

【讨论】:

如果用户不提供自己的值,userParams.MaxPrice的默认值为999999999。我一直在调试代码,userParams.MaxPrice不为空。 以前这是有效的,但第二天它开始显示错误。 调试并单步执行。您会看到您对 userParams 对象的假设一定是不正确的。获取您列出的错误的唯一方法是使用空值。 我已经调试并逐步完成了每个步骤,并检查了 maxPrice 的值,它确实不为空。如果用户不提供自己的值,则应用默认值。当用户提供他们的价值时,我已经确认它在我调试时显示。我不知道这个问题的真正原因是什么。 我终于找到了问题所在。我必须逐步检查导致检查 MaxPrice 值的每个过程,并找到一个先前的 if 语句,该语句更改了 products 的值,从而将 MaxPrice 分配为 null。

以上是关于实体框架在执行 lambda 表达式时抛出错误的主要内容,如果未能解决你的问题,请参考以下文章

实体框架在使用 Find 方法时抛出异常

如何“不是”实体框架的 lambda 表达式

实体框架 - 无法将 lambda 表达式转换为类型“字符串”,因为它不是委托类型

帮助我使用实体框架从 SQL 转换为 linq 嵌套 lambda 表达式

当有任何 SOAP 请求的挂起的实体框架数据库迁移时抛出 SOAP 异常

Lambda vs LINQ-“表达式总是错误的”