Как автоматизировать это (отображение элементов)

У меня есть что-то вроде этого

public class ProductViewModel
{
  public int SelectedProductId { get; set; }
  public string ProductName {get; set;}
  public int Qty {get; set;}
   public List<SelectListItem> Products { get; set}; 
}

У меня есть такой домен

public class Product
{
  public int ProductId {get; set;}
  public string ProductName {get; set;}
  public int Qty {get; set;}
}


public class Store
{
  public Product() {get; set;}
}

Теперь мне нужно сделать сопоставление.

//в моем контроллере

var result = Mapper.Map<ProductViewModel, Store>(Product);

это ничего не свяжет, поскольку он не может понять, как поставить ProductId, поскольку он

Store.Product.ProductId;

Моя карта похожа на это

Mapper.CreateMap<ProductViewModel, Store>().ForMember(dest => dest.Product.ProductId, opt => opt.MapFrom(src => src.SelectedProductId));

Я получаю эту ошибку

Выражение 'dest = > Преобразование (dest.Product.SelectedProductId) должно разрешить члену верхнего уровня. параметр name: lambdaExpression

Я не уверен, как это сделать.

Ответ 1

Ошибка при получении происходит потому, что вы не можете объявлять объявления объявлений более одного уровня в графе объектов.

Поскольку вы только разместили одно свойство, мне сложно дать вам коды, которые сделают эту работу. Один из вариантов заключается в том, чтобы изменить свойство viewmodel на MyTestTestId, и соглашения автоматически подберут это.

Ответ 2

Чтобы сопоставить вложенные структуры, вам просто нужно создать новый объект в аргументе MapFrom.

Пример

Mapping:

Mapper.CreateMap<Source, Destination>()
      .ForMember(d => d.MyNestedType, o => o.MapFrom(t => new NestedType { Id = t.Id }));
Mapper.AssertConfigurationIsValid();

Тестовый код:

var source = new Source { Id = 5 };
var destination = Mapper.Map<Source, Destination>(source);

Классы:

public class Source
{
    public int Id { get; set; }
}

public class Destination
{
    public NestedType MyNestedType { get; set; }
}

public class NestedType
{
    public int Id { get; set; }
}

Ответ 3

Вы можете использовать Resolver.

Создайте класс резольвера:

class StoreResolver : ValueResolver<Store, int>
{
    protected override int ResolveCore(Store store)
    {
        return store.Product.ProductId;
    }
}

И используйте его так:

Mapper.CreateMap<ProductViewModel, Store>()
        .ForMember(dest => dest.SelectedProductId, opt => opt.ResolveUsing<StoreResolver >());

Надеюсь, это поможет...

Ответ 4

Правильный ответ, заданный allrameest по этому вопросу, должен помочь: AutoMapper - отображение глубокого уровня

Это то, что вам нужно:

Mapper.CreateMap<ProductViewModel, Store>()
    .ForMember(dest => dest.Product, opt => opt.MapFrom(src => src));
Mapper.CreateMap<ProductviewModel, Product>()
    .ForMember(dest => dest.ProductId, opt => opt.MapFrom(src => src.SelectedProductId));

ПРИМЕЧАНИЕ. Вы должны попытаться уйти от использования Mapper.CreateMap в этот момент, он устарел и скоро будет не поддерживается.