Comment utiliser une Fonction dans une expression avec Linq to Entity Framework?
Je suis en train d'écrire un linq to entité de la méthode d'extension qui prend un Func pour sélectionner un Id de propriété et de le comparer à une liste d'id.
Classes
public class A
{
public int AId { get; set; }
}
public class B
{
public int BId { get; set; }
}
Méthode D'Extension
public static IQueryable<T> WithId<T>(this IQueryable<T> entities,
Func<T, int> selector, IList<int> ids)
{
Expression<Func<T, bool>> expression = x => ids.Contains(selector(x));
return entities.Where(expression); //error here (when evaluated)
}
Appelant La Méthode
var ids = new List<int> { 1, 2, 3 };
DbContext.EntityAs.WithId(e => e.AId, ids);
DbContext.EntityBs.WithId(e => e.BId, ids);
Le problème que je rencontre est qu'il essaye d'Appeler la fonction qui n'est pas autorisé dans le Cadre de l'Entité.
Comment puis-je utiliser un sélecteur de propriété (Func) pour évaluer la requête?
- Le champ d'application du code, que vous pouvez ouvrir dans une requête EF est limitée par le fait qu'il doit toujours être traduite en SQL. Dans votre cas, EF ne sais pas comment traduire un IList automatiquement.
- Je ne suis pas sûr que vous êtes correct avec ça. DbContext.EntityAs.Où e => id.Contient e.Id)) est traduit par EF correctement. Je suis juste essayer de faire un ré-utilisable de la fonction afin que je puisse définir la propriété à sélectionner sur.
- Parce que EF sait comment faire
select x where x in (1,2,3)
dans le cas de l'énumération ouselect x where x in (select y)
dans le cas d'une autre entité-relation. Dans votre cas, EF besoin de compiler quelque chose commeselect x where x in (select y where F(y) in (F(1),F(2),...))
. Alors qu'il est possible de le faire manuellement EF juste ne supporte pas encore le cas - Il devrait évaluer pour sélectionner x où F(y) (1,2,3) où F(y) serait évalué à x.L'aide ou l'x.Candidature? Est-il un moyen de le faire manuellement dans une arborescence d'expression?
Vous devez vous connecter pour publier un commentaire.
Vous aurez à passer un
Expression<Func<T, int>>
au lieu d'uneFunc<T, int>
et de construire l'expression complète de vous-même. Cela fera l'affaire:Lorsque vous essayez de garder votre code SEC lorsque vous travaillez avec votre O/RM, vous aurez souvent à jouer avec des arbres d'expression. Voici un autre exemple amusant.
WithId()
mais comment pourrais-je le changer pourWithoutId()
/NotWithId()
? Je ne suis pas sûr de l'endroit où à lieu l'opération de négation?Expression.Not
.