web-dev-qa-db-fra.com

comment mapper un objet anonyme à une classe avec AutoMapper?

J'ai une entité:

public class Tag {
    public int Id { get; set; }
    public string Word { get; set; }
    // other properties...
    // and a collection of blogposts:
    public ICollection<Post> Posts { get; set; }
}

et un modèle:

public class TagModel {
    public int Id { get; set; }
    public string Word { get; set; }
    // other properties...
    // and a collection of blogposts:
    public int PostsCount { get; set; }
}

et j'interroge l'entité comme ceci (par EF ou NH):

var tagsAnon = _context.Tags
    .Select(t => new { Tag = t, PostsCount = t. Posts.Count() })
    .ToList();

Maintenant, comment mapper la tagsAnon (en tant que objet anonyme ) à une collection de TagModel (par exemple ICollection<TagModel> ou IEnumerable<TagModel>)? C'est possible?

32
agent47

Oui c'est possible. Vous devez utiliser la méthode DynamicMap de la classe Mapper de Automapper pour chaque objet anonyme que vous possédez. Quelque chose comme ça:

var tagsAnon = Tags
    .Select(t => new { t.Id, t.Word, PostsCount = t.Posts.Count() })
    .ToList();

var tagsModel = tagsAnon.Select(Mapper.DynamicMap<TagModel>)
    .ToList();

Update : DynamicMap est maintenant obsolète .

Maintenant, vous devez créer un mappeur à partir d'une configuration qui définit CreateMissingTypeMaps sur true:

var tagsAnon = Tags
    .Select(t => new { t.Id, t.Word, PostsCount = t.Posts.Count })
    .ToList();

var config = new MapperConfiguration(cfg => cfg.CreateMissingTypeMaps = true);
var mapper = config.CreateMapper();

var tagsModel = tagsAnon.Select(mapper.Map<TagModel>)
    .ToList();
56
Caio Proiete

Je ne suis pas tout à fait sûr que cela soit possible. Suggestions:

Pourquoi ne pouvez-vous pas simplement faire ceci:

var tagsAnon = _context.Tags
    .Select(t => new TagModel { Tag = t, PostsCount = t. Posts.Count() })
    .ToList();

Cela DEVRAIT fonctionner, mais cela échoue (j'ai lu que DynamicMap est incertain pour les collections.

var destination = Mapper.DynamicMap<IEnumerable<TagModel>>(tagsAnon);

Cela prouve que DynamicMap fonctionne avec des types anon, mais apparemment pas avec des énumérables:

var destination = Mapper.DynamicMap<TagModel>(tagsAnon);
2
Justin Pihony

Vous pouvez créer une fonction personnalisée pour y parvenir avec le dernier Automapper. Il utilise la propriété CreateMissingTypeMaps comme mentionné dans d'autres réponses ci-dessus.

public static List<T> MapDynamicList<T>(IEnumerable<object> obj)
    {
        var config = new MapperConfiguration(c => c.CreateMissingTypeMaps = true);
        var mapper = config.CreateMapper();

        var newModel = obj.Select(mapper.Map<T>).ToList();

        return newModel;
    }

Ensuite, vous appelez simplement la fonction avec cette seule ligne de code:

var viewModel = Models.Helper.MapDynamicList<MatchSubCategory>(model);

model est le IEnumerable<object> ou List<object>.

0
vohrahul