je la méthode suivante dans une classe d'accès aux données qui utilise Entity Framework:Passer une requête GetWhere (Func <entityDTO, bool>) à une méthode de couche de données qui a besoin d'un (Func <entity,bool>) paramètre à travailler
public static IEnumerable<entityType> GetWhere(Func<entityType, bool> wherePredicate)
{
using (DataEntities db = new DataEntities())
{
var query = (wherePredicate != null)
? db.Set<entityType>().Where(wherePredicate).ToList()
: db.Set<entityType>().ToList();
return query;
}
}
Cela fonctionne bien lorsque j'utilise les entités à travers toutes les couches ... mais je suis en train de passer à l'aide d'une classe DTO et je voudrais faire quelque chose comme ce qui suit:
public static IEnumerable<EntityTypeDTO> GetWhere(Func<EntityTypeDTO, bool> wherePredicate)
{
//call a method here which will convert Func<EntityTypeDTO,bool> to
// Func<EntityType,bool>
using (DataEntities db = new DataEntities())
{
var query = new List<EntityType>();
if (wherePredicate == null)
{
query = db.Set<EntityType>().ToList();
}
else
{
query = (wherePredicate != null)
? db.Set<EntityType>().Where(wherePredicate).AsQueryable<EntityType>().ToList()
: db.Set<EntityType>().ToList();
}
List<EntityTypeDTO> result = new List<EntityTypeDTO>();
foreach(EntityType item in query)
{
result.Add(item.ToDTO());
}
return result;
}
}
Essentiellement, je veux une méthode qui va convertir Func en Func.
Je pense que je dois décomposer le Func dans un arbre d'expression, puis le reconstruire d'une manière ou d'une autre dans entityType?
Je veux faire ceci pour permettre au calque de présentation de passer juste les requêtes d'expression? Ai-je manqué quelque chose de basique ou existe-t-il un modèle de conception plus facile qui peut transmettre une requête d'un DTO à une classe d'accès aux données sans connaître les détails de la requête?
J'ai essayé de faire en sorte que le DTO hérite de l'entité qui ne semble pas fonctionner non plus?
S'il y a un meilleur modèle de conception que je suis absent, j'aimerais un pointeur et je peux étudier à partir de là ...
Si GetProducts retourne un IQueryable plutôt que d'un IEnumerable et les deux instances puis Entity Framework GetProductsInCategory et GetProductsWithinPriceRange et renvoient IQueryable sera en mesure de prendre tout ce travail et de le convertir en une seule instruction SQL qui signifie que le filtrage est Tout est fait dans la base de données et pas en mémoire dans votre couche d'accès. Lorsque vous filtrez IEnumerable alors vous le faites en mémoire mais tant que vous travaillez sur IQueryable le travail peut être déchargé à la base de données. –
Pour votre Plan B, il y aura quelques complications dans la combinaison de vos fonctions de critères - vous voulez que chacune soit une Expression plutôt qu'un Func pour qu'EF puisse les traduire en SQL clauses (et évitent d'avoir à faire le filtrage en mémoire, ce qui nécessiterait probablement beaucoup plus de données de la base de données que ce qui est strictement nécessaire). Il y a un exemple de code dans une réponse que j'ai laissée sur une autre question qui devrait aider: http://stackoverflow.com/a/37907316/3813189 –