带表达式函数的谓词出错

时间:2015-03-06 23:17:12

标签: c# linq entity-framework predicate

我在LINQ中使用表达式函数用于谓词Where方法(返回IQueryable结果),它接受一个类参数:

    public ActionResult FilterProfiles(FilterViewModel filter)
    {
        var profiles = database.Profiles
            .Where(Predicate(filter))
            ...
    }

谓词是:

    private static Expression<Func<UserProfile, bool>> Predicate(FilterViewModel f)
    {
       return p => (CompareFilter(p, f));
    }

问题在于CompareFilter函数:

    private static bool CompareFilter(UserProfile profile, FilterViewModel filter)
    {
        if (filter.FirstName != null)
        {
            if (profile.FirstName != null)
            {
                if (profile.FirstName.CompareTo(filter.FirstName) != 0)
                {
                    return false;
                }
            }
       ...
      }

例外是:

LINQ to Entities无法识别方法&#39; Boolean CompareFilter(Project.Models.UserProfile,Project.Web.ViewModels.FilterViewModel)&#39;方法,并且此方法无法转换为商店表达式。

异常详细信息:System.NotSupportedException:LINQ to Entities无法识别方法&#39; Boolean CompareFilter(Project.Models.UserProfile,Project.Web.ViewModels.FilterViewModel)&#39;方法,此方法无法转换为商店表达式。

提前致谢!

1 个答案:

答案 0 :(得分:1)

问题在于您尝试在实体框架翻译的lambda中使用方法。

实体框架实际上正在使用IQueryable将您的方法调用转换为SQL,以便无缝地查询数据库。但是,这意味着定义的任何方法本身都在Entity Framework的范围之外,因此无法将其转换为SQL,因此失败。即使您知道源代码,Expression函数也无法作为表达式树访问已编译的方法。

这方面的工作(以及许多其他类似的情况)是使用.AsEnumerable(),这将导致Linq调用进一步成为IEnumerable版本,通过foreach进行枚举,从而拉动我们的对象进入记忆。