Comment faire pour utiliser des prédicats dans LINQ to entities pour Entity Framework objets
Je suis en utilisant LINQ to entities pour Entity Framework objets dans ma Couche d'Accès aux Données.
Mon but est de filtrer autant que je peux à partir de la base de données, sans appliquer une logique de filtrage en mémoire les résultats.
Pour que le but de la Couche Logique Métier passe par un prédicat à la Couche d'Accès aux Données.
Je veux dire
Func<MyEntity, bool>
Donc, si j'utilise ce prédicat directement, comme
public IQueryable<MyEntity> GetAllMatchedEntities(Func<MyEntity, Boolean> isMatched)
{
return qry = _Context.MyEntities.Where(x => isMatched(x));
}
Je suis l'exception
[Système.NotSupportedException] --- {"L'expression LINQ type de nœud
'Appeler' n'est pas pris en charge dans LINQ to entities."}
Solution dans question suggère d'utiliser des AsExpandable() la méthode de LINQKit bibliothèque.
Mais encore une fois, à l'aide de
public IQueryable<MyEntity> GetAllMatchedEntities(Func<MyEntity, Boolean> isMatched)
{
return qry = _Context.MyEntities.AsExpandable().Where(x => isMatched(x));
}
Je suis l'exception
Impossible de convertir l'objet de type
'Système.Linq.Les Expressions.FieldExpression' de type
'Système.Linq.Les Expressions.LambdaExpression'
Est-il moyen d'utiliser le prédicat dans la requête LINQ to entities pour Entity Framework objets, de sorte qu'il est correctement transformé en une instruction SQL.
Merci.
- Je ne veux pas interférer, mais les exposer
IQueryable
et l'expression des paramètres est généralement considéré comme une mauvaise idée. Il est préférable d'ajouter de la spécification des paramètres pourGetAllMatchedEntities
(commeint minimumAge
) et de construire la requête à l'intérieur de la méthode.
Vous devez vous connecter pour publier un commentaire.
Vous n'avez pas besoin LinqKit pour ce faire. N'oubliez pas d'utiliser
au lieu de
Quelque chose comme ceci:
Vous devez utiliser l'Expression Linq to entities besoins pour faire traduire vos lambda SQL.
Lorsque vous utilisez la touche Func votre lambda est compilé à l'IL mais lors de l'utilisation de l'Expression c'est une expression de l'arbre que Linq to entities peut transverse et de les convertir.
Cela fonctionne avec des expressions Linq to entities comprend.
Si elle continue à défaut, alors votre expression ne fait quelque chose que Linq to entities ne peut pas les traduire à SQL. Dans ce cas, je ne pense pas que LinqKit aidera.
Edit:
Il n'y a pas de conversion nécessaire. Il suffit de définir la méthode GetAllMatchedEntities avec un paramètre d'Expression et de l'utiliser de la même manière que vous le feriez avec un paramètre Func. Le compilateur fait le reste.
Il existe trois méthodes que vous pouvez utiliser GetAllMatchedEntities.
1) Avec une ligne d'expression lambda:
2) Définir votre Expression comme un champ (peut être une variable aussi)
3) Vous pouvez créer votre expression manuellement. Le redimensionnement est plus de code, et vous oubliez les contrôles de compilation.
public Boolean IsMatched(MyEntity entity) { return entity.Age > 18; }
pour mon prédicat - comment peut-il être converti àExpression<Func<MyEntity, bool>>
?Argument 1:cannot convert from 'method group' to 'System.Linq.Expressions.Expression<System.Func<TEntity, bool>>'
. Ressemble compilateur attendthis.GetAllMatchedEntities(this.IsMatched(SOMETHING))
au lieu dethis.GetAllMatchedEntities(this.IsMatched)
..Méthodes utilisées dans Linq to entities doit être canoniquement mappé par le fournisseur Linq pour travailler. Depuis le fournisseur Linq, EF, dans votre cas, a été incapable de faire un plan de votre prédicat à une méthode interne, il a jeté une erreur.
Source: CLR Méthode Canonique de la Fonction de Cartographie (http://msdn.microsoft.com/en-us/library/bb738681.aspx)
Vous pouvez essayer de prendre les méthodes qui SONT cartographiés et de la chaîne dans votre expression Linq, ou l'utilisation d'une procédure stockée. Mais jusqu'à ce que EF prend en charge l'ensemble de la CLR, vous serez à gauche avec l'obligation de trouver un travail autour de.
Sur le côté de plus, chaque nouvelle version semble ajouter un peu plus de la liste canonique.
La peine de lire comme une possible solution de contournement: http://msdn.microsoft.com/en-us/library/dd456857.aspx