Проблеми с изравняването на Automapper

Нов съм в Automapper, така че това вероятно е просто решение, но имам проблеми с изравняването на обекти. Например имам следното db извикване:

var le = db.LeagueEvents.Include("Venue").Include(p => p.venue.place).ToList();

Ето как изглеждат LeagueEvents, Venue и Place:

public class LeagueEvent
{
    public int EventId { get; set; }
    public string EventTitle { get; set; }
    public Venue venue { get; set; }
}

public class Venue
{
    public string VenueName { get; set; }
    public Place place { get; set; }
}

public class Place
{
    public string address { get; set;}
}

Сега, когато правя директно преобразуване във VM на DailyEvent, това се картографира добре

        Mapper.CreateMap<LeagueEvent, LeagueEventViewModelDailies>();
        Mapper.CreateMap<Place, PlaceViewModel>();
        Mapper.CreateMap<Venue, VenueViewModelDailies>();

Но когато се опитам да го изравня с помощта на vm като:

 public class DailyEventVM
{
    public int EventId { get; set; }
    public string EventTitle { get; set; }
    public string VenueName { get; set; }
    public string address { get; set; }
}

Връщам нули за VenueName и address

Трябва ли да направя нещо като:

.ForMember(dest => dest.VenueName, opts => opts.MapFrom(src => src.Venue.VenueName)

Ако е така, има ли "групов" начин да се направи това, защото можех да видя, че става доста сложно с голям брой полета за картографиране.

АКТУАЛИЗАЦИЯ Започвам да си мисля, че може да има нещо общо с EF и прокси обекти. Тъй като следното работи:

            Mapper.CreateMap<LeagueEvent, LeagueEventViewModelDailies>()
            .ForMember(d => d.Address, opt => opt.ResolveUsing(src => src.venue.place.Address))
            .ForMember(d => d.AptUnit, opt => opt.ResolveUsing(src => src.venue.place.AptUnit))
            .ForMember(d => d.City, opt => opt.ResolveUsing(src => src.venue.place.City))
            .ForMember(d => d.State, opt => opt.ResolveUsing(src => src.venue.place.State))
            .ForMember(d => d.PostalCode, opt => opt.ResolveUsing(src => src.venue.place.PostalCode))
            .ForMember(d => d.Latitude, opt => opt.ResolveUsing(src => src.venue.place.Latitude))
            .ForMember(d => d.Longitude, opt => opt.ResolveUsing(src => src.venue.place.Longitude))
            .ForMember(d => d.VenueName, opt => opt.ResolveUsing(src => src.venue.VenueName))
            .ForMember(d => d.VenueDescription, opt => opt.ResolveUsing(src => src.venue.Description))
            .ForMember(d => d.PrimaryPhone, opt => opt.ResolveUsing(src => src.venue.PrimaryPhone))
            .ForMember(d => d.SecondaryPhone, opt => opt.ResolveUsing(src => src.venue.SecondaryPhone))
            .ForMember(d => d.Link, opt => opt.ResolveUsing(src => src.venue.Link));

И те работят (независимо едно от друго):

lvm = Mapper.Map<Venue, LeagueEventViewModelDailies>(l.venue);
            lvm = Mapper.Map<Place, LeagueEventViewModelDailies>(l.venue.place);

използвайки всяко от горните поотделно, те връщат правилно информацията за мястото или мястото.

Въпреки това, следното все още връща нула за място и място:

lvm = Mapper.Map<LeagueEvent, LeagueEventViewModelDailies>(l);

Когато задълбочавам и разглеждам "l", място и място са прокси обекти и мисля, че това е причината за нулевите стойности.

Първият пример беше подмножество от това, с което работя за краткост.

Както винаги благодаря за помощта,


person Chris    schedule 28.12.2015    source източник
comment
Нямам време да създавам пример в момента, но погледнете github.com/ AutoMapper/AutoMapper/wiki/Flattening . „Ако за което и да е свойство от типа местоназначение свойство, метод или метод с префикс Get не съществува в типа източник, AutoMapper разделя името на члена местоназначение на отделни думи (чрез конвенциите на PascalCase).“   -  person Eris    schedule 28.12.2015
comment
Благодаря ти за бързия отговор. Разгледах това, преди да публикувам и с някои допълнителни тестове това, което се случва, е, че обектът Venue не е картографиран, но обектът Place е. За момента продължих и използвах метода formember и той вече работи, но наистина бих искал да разбера защо мястото не е картографирано напълно.   -  person Chris    schedule 29.12.2015


Отговори (2)


Причината, поради която името на мястото не е картографирано, е, че не е наименувано последователно. Във вашия целеви клас той се нарича VenueName, който автоматично преобразувател ще приеме като (src).Venue.Name, но в класа Venue членът се нарича VenueName.

Вашите опции:

  1. Преименувайте Venue.VenueName на Venue.Name
  2. Преименувайте DailyEventVM.VenueName на DailyEventVM.VenueVenueName

Използвайки същата логика, свойството адрес трябва да се извика DailyEventVM.VenuePlaceAddress, което Automapper ще раздели на регистър на паскалите, за да бъде (src).Venue.Place.Address

person Eris    schedule 28.12.2015

Можете да картографирате няколко изходни обекта към един целеви обект (като вашия VM обект), много по-лесно е да конфигурирате:

public class Src1
{
    public string P1 { get; set; }
}

public class Src2
{
    public string P2 { get; set; }
}

public class Dest
{
    public string P1 { get; set; }
    public string P2 { get; set; }
}

И картографирането:

Mapper.CreateMap<Src1, Dest>();
Mapper.CreateMap<Src2, Dest>();

var src1 = new Src1 { P1 = "foo" };
var src2 = new Src2 { P2 = "bar" };
var dest = new Dest();

Mapper.Map(src1, dest);
Mapper.Map(src2, dest);

Assert.AreEqual("foo", dest.P1);
Assert.AreEqual("bar", dest.P2);
person Ilya Chumakov    schedule 28.12.2015