2017-09-06 1 views
2

Dans ma base de données, j'ai des tables d'étiquettes et de publications. Il y a une relation plusieurs-à-plusieurs entre eux. Dans l'entité Tag, je ne stocke pas le nombre de fois que la balise a été utilisée. Cette propriété (Quantity) est à l'intérieur du modèle de vue d'étiquette.Définition d'une propriété de View Model dans la méthode AfterMap (AutoMapper) de manière asynchrone

En utilisant AutoMapper, je crée une carte entre Tag et TagViewModel. A l'intérieur méthode AfterMap I mis Quantity propriété:

Mapper.Initialize(config => 
{ 
    config.CreateMap<Tag, TagViewModel>() 
     .AfterMap(async (m, vm) => 
     { 
      vm.Quantity = await tagRepository.CountById(vm.Id); 
     }); 
}); 

Le problème est que ce code ne fonctionne pas toujours. Parfois Quantity est réglé correctement, est parfois défini comme 0 et parfois je reçois une exception:

BeginExecuteReader requires an open and available Connection. The connection's current state is open. 

Comment puis-je résoudre ce problème ou ce qui est une meilleure solution pour régler la valeur de Quantity automatiquement après la cartographie?

Voici le reste de mon code:

Entités:

public class Tag 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<TagPost> TagPost { get; set; } = new HashSet<TagPost>(); 
} 

public class Post 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public string Author { get; set; } 
    public string Content { get; set; } 

    public virtual ICollection<TagPost> TagPost { get; set; } = new HashSet<TagPost>(); 
} 

public class TagThread 
{ 
    public int PostId { get; set; } 
    public Post Post { get; set; } 

    public int TagId { get; set; } 
    public Tag Tag { get; set; } 
} 

Tag voir le modèle:

public class TagViewModel 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int Quantity { get; set; } 
} 

Repository:

public async Task<int> CountById(int id) 
{ 
    var quantity = await context.Tags 
     .SelectMany(t => t.TagPost.Where(c => c.TagId == id)) 
     .CountAsync(); 

    return quantity; 
} 

Répondre

3

Vous avez une propriété de navigation sur votre tag classe, alors pourquoi ne pas faire ceci:

config.CreateMap<Tag, TagViewModel>() 
    .ForMember(d => d.Quantity, o => o.MapFrom(s => s.TagPost.Count); 
+0

Oui, mais cela doit être utilisé avec ProjectTo. –

+0

ProjectTo fonctionne avec MapFrom, car MapFrom accepte une Expression >, de sorte qu'il peut être transféré dans SQL. Si j'avais utilisé ResolveUsing, ce ne serait pas une Expression >. – Jack

+0

Oui, je disais juste que cela devrait faire partie de votre réponse, car la question implique Map, parce qu'elle a cette AfterMap. –