无法从表达式中提取此函数

时间:2017-03-27 22:46:01

标签: c# entity-framework entity-framework-core

我尝试参数化实体框架查询(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()
}

这看起来很奇怪 - 我认为他们应该采取同样的行动。为什么会发生这种情况?

2 个答案:

答案 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>>才能理解表达式树。