Ce que j'ai écrit dans l'article, j'ai pris environ 10 heures, c'était 10 heures de débogage continu, ce qui a réduit à une comparaison étape par étape des versions de travail et non fonctionnelle du code, pas même cela, à comparer chaque ligne de la fenêtre de débogage des versions de travail et non fonctionnelle du code
Pour un programmeur qui n'est pas familier avec les arborescences d'expressions, un bon article introductif sur msdn révèle en détail certaines étapes de la construction d'une arborescence que j'ai omise dans l'article.
Dans ce cas, ce test sera vert (le complément EF est activé, dans lequel il se bloque s'il ne peut pas traduire complètement la requête en SQL ).

- Tout d'abord, le mappage du champ PupilName doit être défini s'il n'est pas défini. Le fournisseur de requêtes ne reconnaît pas sur quoi la propriété PupilName doit être projetée pour s'ajouter à SQL ORDER BY .
Deuxièmement, le fournisseur doit analyser ce mappage, par exemple, cela ne fonctionnera pas, EF commencera à jurer (par défaut, il ne jure pas, il soulève des entités en mémoire - LINQ to Object , mais cela peut être activé ):

Et le fait est que le fournisseur de requêtes ne comprend pas par quelle (s) propriété (s) de l'entité nous voulons trier. Mais si le mappage est écrit correctement, le fournisseur s'en sortira, enverra une requête SQL , recevra une réponse et désérialisera les résultats.
Parfois, il devient nécessaire d'écrire vous-même des expressions , c'est-à-dire quelque chose de similaire:

Je vais vous montrer comment écrire cette expression , ce n'est pas si difficile, le lien ci-dessus fournit plusieurs exemples similaires:

Nous collectons le lambda étape par étape, d'abord un paramètre, une propriété, puis nous collons tout.
Dans ce cas, cela ne fonctionnera pas et le test sera vert (le fournisseur ne sera pas en mesure d'analyser l'expression)?
Je ne sais pas? Ne vous inquiétez pas, je ne le savais pas non plus et finalement j'ai mis environ 10 heures à comprendre.
Voici un indice, cela fonctionnera:

PupilDto hérite de PupilDtoBase Le fait est que PropertyInfo doit être extrait de la classe de base si la propriété PupilName elle-même appartient à la classe de base, donc C # construit l' expression lambda et EF les analyse, en s'appuyant sur les normes de langage
PreuvesCe que le débogueur montre si vous écrivez un lambda normal dans OrderBy :

Et dans notre cas, comme ceci:

AutoMapper et IncludeBase
Si vous essayez de ne pas dupliquer le code, vous avez probablement rencontré l'héritage de DTO et IncludeBase :

Il y a une situation encore plus sophistiquée:

Et ce test sera vert:

Et la chose est la même, encore une fois PropertyInfo est extrait de l'interface:

PreuvesLe ReflectedType de la propriété Age est une interface, IPupilDto , C # construit un lambda, dans lequel la propriété Age est une propriété de la classe PupilDto, pas une interface, mais voici comment l'automappeur construit un lambda:

Comment résoudre ce problème? Si IncludeBase Automapper avec une interface ne nous convient pas (si vous utilisez le mappage en mémoire - cela ne vous affectera pas), alors vous devrez abandonner cette API, j'ai résolu ce problème en mettant en surbrillance le mappage dans la méthode d'extension , comme ceci:

Ensuite, le mappeur automatique lui-même trouvera une propriété de type appropriée par nom, construira un lambda «correct»
Merci de votre attention!