我尝试参数化实体框架查询(EntityFrameworkCore 1.1.1),但是我从" Where"中提取函数时遇到错误。表达:
System.NotSupportedException:
无法解析表达式school.Programs.Any(__ p_0)':给定的参数与预期的参数不匹配:类型的对象' System.Linq.Expressions.TypedParameterExpression&#39 ;无法转换为' System.Linq.Expressions.LambdaExpression'。
当我尝试拨打SearchSchools()
时,我收到了错误:
public IQueryable<SchoolResult> SearchSchoolQueryable(
Expression<Func<School, bool>> schoolExpression)
{
return _dbContext.School
.Where(schoolExpression)
.Select(s => new SchoolResult
{
Id = s.Id,
Name = s.Name
}
);
}
// hardcoded test: doesn't work
public async Task<IEnumerable<SchoolResult>> SearchSchools()
{
Func<Program, bool> p = program => program.Name.StartsWith("U");
Expression<Func<School, bool>> expr = school => school.Active
&& school.Programs.Any(p);
return await SearchSchoolQueryable(expr)
.ToListAsync()
}
但是,当我重写SearchSchools以便Func
内联时,它工作正常:
// hardcoded test: works ok
public async Task<IEnumerable<SchoolResult>> SearchSchools()
{
Expression<Func<School, bool>> expr = school => school.Active
&& school.Programs.Any(program => program.Name.StartsWith("U"));
return await SearchSchoolQueryable(expr)
.ToListAsync()
}
这看起来很奇怪 - 我认为他们应该采取同样的行动。为什么会发生这种情况?
答案 0 :(得分:1)
您的第二个示例有效,因为您有Expression
代表Func<Program, bool>
的创建。您需要拥有 Func<Program, bool>
,因为这是Any
期望的内容,但Func
的所有详细信息都必须位于Expression
中1}}以便查询提供者可以看到所有这些信息并进行处理。
在您的第一个示例中,Func<Program, bool>
是在代码中创建的,而不是在Expression
中创建的,因此它只是常规的旧编译代码,并且查询提供程序没有足够的将一些任意.NET代码转换为SQL的信息,所以它所能做的只是举起手来。
答案 1 :(得分:0)
第一种情况中的错误是您将p
声明为Func<Program, bool>
。
实体框架必须是Expression<Func<Program, bool>>
才能理解表达式树。