Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.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#EF Core QueryableExtensions.FirstOrDefaultAsync异常行为_C#_Generics_Entity Framework Core_Expression - Fatal编程技术网

C#EF Core QueryableExtensions.FirstOrDefaultAsync异常行为

C#EF Core QueryableExtensions.FirstOrDefaultAsync异常行为,c#,generics,entity-framework-core,expression,C#,Generics,Entity Framework Core,Expression,我有一个通用存储库,向其传递表达式过滤器。例如,此表达式如下所示: filterExpr = part => (filter.ProductId != null ? filter.ProductId == part.ProductId : true) && (filter.SerialNumber != null ? filter.SerialNumber == part.SerialNumber : true); 在存储库中,我在从DbContext获得

我有一个通用存储库,向其传递
表达式过滤器
。例如,此表达式如下所示:

filterExpr = part =>
    (filter.ProductId != null ? filter.ProductId == part.ProductId : true) &&
    (filter.SerialNumber != null ? filter.SerialNumber == part.SerialNumber : true);
在存储库中,我在从DbContext获得的DbSet上调用
QueryableExtensions.FirstOrDefaultAsync(filterExpr)

this.dbSet = context.Set<TEntity>()
// ....
IQueryable<TEntity> query = dbSet;
return query.FirstOrDefaultAsync(filter);
Edit2:我当前的解决方法是测试所有过滤器属性的
null
值,并且仅当至少在属性上与
null
不同时才计算过滤器

private bool AllPropertiesNull(object obj)
{
    return !obj.GetType().GetProperties().Any(propInfo => propInfo.GetValue(obj) != null);
}
然后:

if(filter != null && AllPropertiesNull(filter))
    filterExp = part => true;

但我想避免这种情况。

根据我使用EF Core的经验,查询转换器试图消除常量谓词表达式,以便生成与使用条件
Where
类似的条件(或根本没有条件)

但是,它似乎能够正确地处理二进制表达式(
&&
|
),但对于条件
?,这样做失败:表达式。您可以向他们的GitHub问题跟踪者报告,但由于他们正在开发EF Core 3.0,我认为在早期版本中不会解决这个问题。而且3.0仍然处于许多事情都不起作用的状态,因此不能用于评估最终版本中是否会起作用

我建议的解决方法(似乎在所有版本中都很有效)是使用等效的基于
|
的条件,例如

filterExpr = part =>
    (filter.ProductId == null || filter.ProductId == part.ProductId) &&
    (filter.SerialNumber == null || filter.SerialNumber == part.SerialNumber); 

根据我使用EF-Core的经验,查询转换器试图消除常量谓词表达式,以便生成与使用条件
Where
类似的条件(或根本没有条件)

但是,它似乎能够正确地处理二进制表达式(
&&
|
),但对于条件
?,这样做失败:表达式。您可以向他们的GitHub问题跟踪者报告,但由于他们正在开发EF Core 3.0,我认为在早期版本中不会解决这个问题。而且3.0仍然处于许多事情都不起作用的状态,因此不能用于评估最终版本中是否会起作用

我建议的解决方法(似乎在所有版本中都很有效)是使用等效的基于
|
的条件,例如

filterExpr = part =>
    (filter.ProductId == null || filter.ProductId == part.ProductId) &&
    (filter.SerialNumber == null || filter.SerialNumber == part.SerialNumber); 

你能展示你的单元测试吗?试着用(1)代替,但是你需要OrderBy,否则它将是随机的。其他用途SingleOrDefault@DIlshodK我添加了测试代码,但我认为这没有帮助。但是,如果在生产环境中返回null而不是给我一个超时,我可以接受它。@Frank Nielsen将空筛选器传递给方法generelly根本没有任何意义,也不应该在生产环境中发生,因此准确返回哪个对象并不重要。只是API应该足够健壮,能够在不崩溃的情况下处理这种情况。我可以检查所有筛选器属性是否为空值,然后跳过筛选,但这会添加许多不必要的代码。我的问题更像是“我做错了什么,或者这是EF的问题,我应该在GitHub上归档吗?”,这不是一个解决方法。谢谢你的建议。你用的是什么EF核心版本?你能展示你的单元测试吗?试着用(1)代替,但你需要订购者-否则它将是随机的什么是第一个。其他用途SingleOrDefault@DIlshodK我添加了测试代码,但我认为这没有帮助。但是,如果在生产环境中返回null而不是给我一个超时,我可以接受它。@Frank Nielsen将空筛选器传递给方法generelly根本没有任何意义,也不应该在生产环境中发生,因此准确返回哪个对象并不重要。只是API应该足够健壮,能够在不崩溃的情况下处理这种情况。我可以检查所有筛选器属性是否为空值,然后跳过筛选,但这会添加许多不必要的代码。我的问题更像是“我做错了什么,或者这是EF的问题,我应该在GitHub上归档吗?”,这不是一个解决方法。谢谢你的建议。你用的是什么英孚核心版本?非常感谢,这就是诀窍,你的解释听起来也很合理。不幸的是,现在我无法使用我的
bool CheckFilter(T filterProp,T checkProp)
,正如我在开始时打算的那样,但我可以用它来生活。非常感谢你,这就做到了,你的解释听起来也很合理。不幸的是,现在我不能像开始时那样使用我的
bool CheckFilter(T filterProp,T checkProp)
,但我可以用它生活。