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

Rya*_*ers 62 c# linq asp.net linq-to-entities entity-framework

在我以后的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Len*_*rri 116

我得到这个非常错误和我使用实体框架与PredicateBuilder乔阿尔巴哈利建立动态where条款.如果您碰巧处于相同状态,则应调用该AsExpandable方法:

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

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

这种方法是LINQKIT DLL,你可以抓住的一部分,在这里或通过NuGet包在这里.

现在一切都很好.:)

  • 您知道`AsExpandable()`是否会对性能产生影响吗?我使用的是通用存储库,偶尔仅使用谓词生成器,是否值得为谓词构建创建单独的存储库方法? (2认同)
  • 看起来在最新版本中您不需要使用 `AsExpandable()` 将谓词传递给 `Where()`。可能是因为新的 `PredicateBuilder.New&lt;T&gt;()` 起点? (2认同)

Jon*_*eet 47

你试图传递一个任意的.NET函数......实体框架怎么可能希望将它转换成SQL呢?你可以改变它来Expression<Func<int, bool>>代替,并Where从中构建子句,虽然它不会特别容易,因为你需要用不同的参数表达式重写表达式(即替换原始表达式中的任何参数表达式)树的表达呼唤u.RelationTypeId).

老实说,为了只u.RelationTypeId在用于创建表达式树的lambda表达式中指定传递给方法,你最好只使用:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Ryan @Marc还有[LinqKit](http://www.albahari.com/nutshell/linqkit.aspx),其中包含了操作表达式所需的许多功能. (2认同)
  • 我第二次克里斯对LinqKit的建议=>它使得表达<Func <YourType,bool >>谓词非常容易. (2认同)

小智 5

您可以在请求之前调用该Expand()方法。predicateWhere