“LINQ to Entities中不支持LINQ表达式节点类型'Invoke'” - 难倒!

时间:2011-03-12 19:32:38

标签: c# asp.net linq entity-framework linq-to-entities

在我以后的EF中,我试图传入一个匿名函数作为我的Linq查询的一部分。该函数将传入INT并返回BOOL(u.RelationTypeId是INT)。以下是我的功能的简化版本:

public IEnumerable<UserBandRelation> GetBandRelationsByUser(Func<int, bool> relation)
{
    using (var ctx = new OpenGroovesEntities())
    {
        Expression<Func<UsersBand, bool>> predicate = (u) => relation(u.RelationTypeId);

        var relations = ctx.UsersBands.Where(predicate);

        // mapping, other stuff, back to business layer
        return relations.ToList();
    }
}

但是,我收到上述错误。看起来我通过从函数构建谓词来使一切正确。有任何想法吗?感谢。

4 个答案:

答案 0 :(得分:114)

我收到了这个错误,我正在使用Joe Albahari的PredicateBuilder实体框架来构建动态where子句。如果您碰巧处于相同状态,则应调用AsExpandable方法:

如果使用 Entity Framework 进行查询,请将最后一行更改为:

  

return objectContext.Products.AsExpandable().Where(predicate);

此方法是LINQKIT DLL的一部分,您可以抓取here或通过NuGet包here

现在一切正常。 :)

答案 1 :(得分:47)

你正试图传递一个任意的.NET函数......实体框架怎么可能希望将它转换为SQL?您可以将其更改为取Expression<Func<int, bool>>,并从中构建Where子句,尽管它不会特别容易,因为您需要重写表达式使用不同的参数表达式(即使用调用u.RelationTypeId的表达式替换原始表达式树中的任何参数表达式。)

老实说,为了在lambda表达式中指定u.RelationTypeId,您可以使用它来创建表达式树以传递给方法,您最好只使用:

public IEnumerable<UserBandRelation> GetBandRelationsByUser(
    Expression<Func<UsersBand, bool>> predicate)
{
    using (var ctx = new OpenGroovesEntities())
    {
        var relations = ctx.UsersBands.Where(predicate);

        // mapping, other stuff, back to business layer
        return relations.ToList();
    }
}

答案 2 :(得分:3)

您可以在 请求

之前在谓词上调用展开()方法

答案 3 :(得分:-8)

我知道这个答案真的很晚了,但我遇到了同样的问题而且它让我在这里,所以我想我会分享我的解决方案。

我读了Leniel的回答,它给了我一个主意。默认类型具有方法“AsEnumerable()”,其行为方式相同,从而缓解了问题。