web-dev-qa-db-fra.com

"Le type de nœud d'expression LINQ 'Invoke' n'est pas pris en charge dans LINQ to Entities" - perplexe!

Dans mon EF plus tard, j'essaie de transmettre une fonction anonyme à utiliser dans le cadre de ma requête Linq. La fonction passerait un INT et retournerait un BOOL (u.RelationTypeId est un INT). Voici une version simplifiée de ma fonction:

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

Cependant, j'obtiens l'erreur indiquée ci-dessus. Il semble que je vais tout correctement en construisant un prédicat à partir de la fonction. Des idées? Merci.

62
Ryan Peters

Vous essayez de passer une fonction .NET arbitraire dans ... comment le framework d'entité pourrait-il espérer traduire cela en SQL? Vous pouvez le modifier pour prendre un Expression<Func<int, bool>> à la place, et construisez la clause Where à partir de cela, bien que ce ne sera pas en particulier facile, car vous devrez réécrire l'expression avec une expression de paramètre différente (c'est-à-dire remplacer quelle que soit l'expression du paramètre dans l'arborescence d'expression d'origine avec l'expression d'appeler u.RelationTypeId).

Pour être honnête, juste pour spécifier u.RelationTypeId dans l'expression lambda que vous utilisez pour créer l'arborescence d'expression à passer dans la méthode, vous feriez mieux d'utiliser simplement:

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

J'obtenais cette erreur et j'utilise Entity Framework avec PredicateBuilder par Joe Albahari pour construire des clauses dynamiques where. S'il vous arrive d'être dans le même état, vous devez appeler la méthode AsExpandable:

Si vous interrogez avec Entity Framework , changez la dernière ligne en ceci:

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

Cette méthode fait partie de LINQKIT DLL que vous pouvez récupérer ici ou via un package NuGet ici .

Tout fonctionne bien maintenant. :)

115
Leniel Maccaferri

Vous pouvez appeler la méthode Expand () sur votre prédicat avant la demande where

3
Zerelli Seifeddine