“The LINQ expression node type 'Invoke' is

2019-01-06 13:44发布

问题:

In my EF later, I'm trying to pass in an anonymous function to be used as part of my Linq query. The function would pass in an INT and return a BOOL (u.RelationTypeId is an INT). Below is a simplified version of my function:

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();
    }
}

However, I get the error stated above. It seems like I'm going everything correct by building a predicate from the function. Any ideas? Thanks.

回答1:

You're trying to pass an arbitrary .NET function in... how could the entity framework hope to translate that into SQL? You can change it to take an Expression<Func<int, bool>> instead, and build the Where clause from that, although it won't be particularly easy, because you'll need to rewrite the expression with a different parameter expression (i.e. replacing whatever parameter expression is in the original expression tree with the expression of calling u.RelationTypeId).

To be honest, for the sake of just specifying u.RelationTypeId in the lambda expression that you use to create the expression tree to pass into the method, you'd be better off just using:

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:

I was getting this very error and I'm using Entity Framework with PredicateBuilder by Joe Albahari to build dynamic where clauses. If you happen to be in the same condition, you should call the AsExpandable method:

If querying with Entity Framework, change the last line to this:

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

This method is part of LINQKIT DLL that you can grab here or through a NuGet package here.

Everything works fine now. :)



回答3:

You can call Expand() methode on your predicate before the where request



回答4:

I know this answer is really late, but I ran into the same problem and it led me here, so I thought I'd share my solution.

I read Leniel's answer, and it gave me an idea. The default types have the method "AsEnumerable()" which behaves the same way, alleviating the issue.