Проблемы с выравниванием Automapper

Я новичок в Automapper, поэтому это, вероятно, простое решение, но у меня возникают проблемы со сглаживанием объектов. Например, у меня есть следующий вызов БД:

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;}
}

Теперь, когда я делаю прямое преобразование в виртуальную машину DailyEvent, все отлично отображается

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

Но когда я пытаюсь сгладить это, используя виртуальную машину, например:

 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