web-dev-qa-db-fra.com

Comment utiliser ProjectTo avec l'injection de dépendance Automapper 8.0

J'utilise le modèle DI d'Automapper (8.0) dans mon projet et je cherche à commencer à utiliser ProjectTo dans mes requêtes d'entité Core Entity Framework.

Voici un exemple de ce que j'ai réussi à faire au travail:

    public async Task<IEnumerable<SomeViewModel>> GetStuffAsync() {

        return await _dbContext.SomeEntity
            .ProjectTo<SomeViewModel>(_mapper.ConfigurationProvider)
            .ToListAsync();
    }

L'appel ci-dessus renvoie tous les enregistrements attendus, mais il nécessite à la fois l'injection d'IMapper dans le constructeur du référentiel ainsi qu'une référence Using à AutoMapper.QueryableExtensions.

Il existe deux versions des documents AutoMapper que j'ai trouvés et qui semblent fournir des informations contradictoires.

Ces documents https://automapperdocs.readthedocs.io/en/latest/Dependency-injection.html indiquent ce qui suit:

L'utilisation de DI est en fait mutuellement exclusive avec l'utilisation de la méthode d'extension IQueryable.ProjectTo. Utilisez plutôt IEnumerable.Select (_mapper.Map) .ToList ().

Et ces documents http://docs.automapper.org/en/stable/Dependency-injection.html indiquent ceci:

À partir de la version 8.0, vous pouvez utiliser IMapper.ProjectTo. Pour les versions plus anciennes, vous devez transmettre la configuration à la méthode d'extension IQueryable.ProjectTo (IConfigurationProvider).

En suivant l'exemple de la première documentation, j'ai converti ma requête en ceci:

    public IEnumerable<SomeViewModel> GetStuff() {

        return _dbContext.SomeEntity
            .Select(_mapper.Map<SomeViewModel>)
            .ToList();
    }

Cependant, cette méthode renvoie 0 enregistrements (le précédent a tout renvoyé) et la méthode devait être convertie d'Async en synchrone car ToListAsync () n'était pas pris en charge par la sélection étendue. De toute évidence, il me manque quelque chose. En outre, je ne suis pas sûr que ce soit la bonne technique car le deuxième ensemble de documents parle de l'utilisation d'IMapper.ProjectTo pour la version 8.0 sans passer la configuration à la méthode d'extension. Comment je fais ça?

9
Alex

À partir de la version 8.0, vous pouvez utiliser IMapper.ProjectTo

Cela signifie que maintenant l'interface IMapper a une méthode ProjectTo (similaire à Map). Donc, même si vous avez encore besoin d'injecter IMapper (mais vous en avez quand même besoin si vous utilisiez Map, donc aucune différence), vous n'avez pas besoin de QueryableExtensions et ProjectTo méthode d'extension - vous utilisez simplement la méthode d'interface (similaire à Map):

return await _mapper.ProjectTo<SomeViewModel>(dbContext.SomeEntity)
    .ToListAsync();

Veuillez noter qu'il existe une différence fondamentale entre _mapper.ProjectTo Et Select(_mapper.Map) - le premier est traduit en SQL et exécuté côté serveur, tandis que le dernier conduit à évaluation client et nécessite Include/ThenInclude (ou chargement paresseux) pour fonctionner correctement.

21
Ivan Stoev