Mapowanie w mapowaniu (Automapper)

Odpowiedz Nowy wątek
2018-10-30 19:33
0

Potrzebuję zmapować joinowane zapytanie klasy Tenant i RelatedUsers (czyli liczba userów powiązanych z organizacją) do klasy TenantDto (przeznaczonej do UI). W środku mapowania muszę wykonać jeszcze jedno mapowanie - gdy daję tam debuggera, wszystko wygląda okej i property mapuje się tak jak powinien. Konfiguracja wygląda tak:

 CreateMap<JoinedTenant, TenantDto>()
                .ForSourceMember(src => src.Tenant, opt => opt.Ignore())
                .AfterMap((src, dest) =>
                {
                    dest = src.MapTo<TenantDto>();
                    dest.RelatedUsers = src.RelatedUsers;
                });

Natomiast kiedy wracam do klasy, gdzie mapowanie zostało wywołane, mapuje się tylko RelatedUsers. Ma ktoś może pomysł, co w takiej sytuacji zrobić?

            result.Items = tenantsQuery
                .Skip(input.SkipCount)
                .Take(input.MaxResultCount)
                .MapTo<List<TenantDto>>();
możesz pokazać jak wyglądają te klasy i opisać lepiej co chcesz osiągnąć? czuję że przekombinowujesz :P - mad_penguin 2018-10-30 20:10

Pozostało 580 znaków

2018-10-30 20:14
0

Tu jest zapytanie, które mi pozwala pobrać Tenanta wraz z przypisanymi do niego użytkownikami

     IQueryable<JoinedTenant> GetTenantWithRelatedUsersQuery()
            {
                var dbcontext = UnitOfWorkManager.Current.GetDbContext<VZeroDbContext>();
                return (from tenant in dbcontext.Tenants
                        join user in dbcontext.Users on tenant.Id equals user.TenantId
                        select new { tenant, user }).GroupBy(grp => grp.tenant)
                    .Select(grp => new JoinedTenant { Tenant = grp.Key, RelatedUsers = grp.Count() });
            }

Tutaj klasa TenantDto

  [AutoMapFrom(typeof(Tenant))]
    public class TenantDto : EntityDto
    {
        [Required]
        [StringLength(AbpTenantBase.MaxNameLength)]
        public string Name { get; set; }

        [Required]
        public string AddressLine { get; set; }

        [Required]
        public string City { get; set; }

        [Required]
        public string ZipCode { get; set; }

        [Required]
        public string Country { get; set; }

        [Required]
        public DateTime CreateDate { get; set; }

        public int RelatedUsers { get; set; }

        public string CreateDateString { get; set; }

        public string Address { get; set; }
    }

I JoinedTenant

    public class JoinedTenant
    {
        public Tenant Tenant;

        public int RelatedUsers;
    }

Z kolei klasa Tenant to po prostu rozszerzona wersja TenantDto, zawierająca niektóre pola niepotrzebne dla widoku.

Pozostało 580 znaków

2018-10-30 20:27
0
.ForSourceMember(src => src.Tenant, opt => opt.Ignore())

Po co ignorujesz skoro docelowo chcesz zmapować ?

Pozostało 580 znaków

2018-10-30 20:33
0

Spróbuj coś takiego:

 CreateMap<JoinedTenant, TenantDto>()
                .ForSourceMember(src => src.Tenant, opt => opt.Ignore())
                .AfterMap((src, dest) =>
                {
                    Mapper.Map(src, dest);
                    dest.RelatedUsers = src.RelatedUsers;
                });

Ewentualnie

CreateMap<Tenant, TenantDto>();
// a potem
Mapper.Map(src.Tenant, dest);

Bo jak dla mnie to wygląda na rekursywne mapowanie w nieskończoność :P Natomiast Twoja wersja przypisuje wartość argumentowi funkcji, zatem zmiana nie wyjdzie na zewnątrz.
Swoją drogą ja bym automapperował samego Tenanta, a RelatedUsers przypisywał ręcznie, wtedy wszystko dzieje się bardziej explicite i nie ma takich problemów.

UPDATE:
Poprawiłem niepotrzebne przypisywanie do dest

edytowany 1x, ostatnio: mad_penguin, 2018-10-30 20:42

Pozostało 580 znaków

2018-10-30 21:09
0

A tak nie zadziała?

CreateMap<JoinedTenant, TenantDto>()
                .ForAllMembers(i =>i.MapFrom(opt=>opt.Tenant));

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0