J'ai lu environ 30 questions Stack Overflow, et environ 20 blogs et ne trouve pas ma réponse. Cela dit, je suis sûr que la réponse que je demande est là, donc si vous le savez, veuillez le signaler (veuillez noter le dernier paragraphe/phrase sur les réponses qui ne correspondent pas à mes exigences). Merci!Expression <Func <TEntity, bool >> imbriquant qui fonctionne avec Entity Framework
Je suis cas persistant de classes qui ont une forme similaire à:
public class Data {
public int Id { get; set; }
}
public class Container {
public int Id { get; set; }
public Data Data { get; set; }
}
Actuellement les requêtes sont écrites pour trouver des conteneurs via une couche d'abstraction qui nécessite une expression Lambda accepter un récipient et retour bool (prédicat). Il n'acceptera pas IQueryable même si Entity Framework 5 est l'ORM de son choix.
Ma tâche consiste à présenter une surface d'API basée sur des expressions lambda acceptant le type de données. Je ne peux pas changer la couche d'abstraction (je dois passer un prédicat qui accepte un conteneur), donc je suis en train de convertir une expression que je reçois comme:
Expression<Func<Data , bool>>
to:
Expression<Func<Container , bool>>
J'ai ajouté une méthode supplémentaire dans ma classe référentiel comme celles-ci:
public Container Find(Expression<Func<Data , bool>> predicate) {
IEnumerable<Container> result = QueryStrategy.Fetch(c => predicate.Compile().Invoke(c.Data));
return result.FirstOrDefault();
}
Ce complimente la méthode Find existant:
public Container Find(Expression<Func<Container , bool>> predicate) {
IEnumerable<Container> result = QueryStrategy.Fetch(predicate);
return result.FirstOrDefault();
}
Lorsque la première méthode est utilisée, elle produit l'exception suivante:
LINQ to Entities ne reconnaît pas la méthode « booléenne Invoke (Container.Data) » méthode, et cette méthode ne peut pas être traduit dans une expression de magasin.
J'ai essayé toutes sortes de choses avec les classes d'expression je ne peux pas voir un moyen de la carte:
Expression<Func<Data , bool>>
to:
Expression<Func<Container , bool>>
Sans utiliser Invoke qui ne sont pas pris en charge par Entity Framework (mais fonctionne très bien avec en mémoire des données énumérables).
Quelqu'un peut-il m'aider à faire fonctionner le scénario ci-dessus en utilisant Expressions? Je comprends que je peux utiliser la librairie LinqKit pour résoudre ce problème, mais je veux vraiment résoudre ce problème sans avoir recours à une bibliothèque tierce. MISE À JOUR: Dans mon effort pour présenter un problème simplifié, j'ai impliqué (en utilisant initialement DbContext dans l'exemple de code) que le code aurait accès à IQueryable et/ou serait approprié pour utiliser AsExpandable() de LinqKit. En réalité, ce n'est pas le cas - la classe repository n'est pas autorisée à utiliser IQueryable ou toute autre extension spécifique au fournisseur. J'ai modifié les exemples ci-dessus et j'espère que cela rend les choses plus claires.
Ce problème est résolu
Est-ce une exigence que le filtrage des conteneurs par votre expression Func a lieu dans la base de données? –
Bonne question - Oui c'est. – FantasticJamieBurns
Une raison particulière pour laquelle vous ne voulez pas apporter une bibliothèque tierce? Comme vous l'avez mentionné ci-dessus, LinqKit peut gérer la composition des expressions comme vous le souhaitez; le faire sans LinqKit nécessiterait probablement de dupliquer beaucoup de ses fonctionnalités. –