如何自动映射这个(映射子成员)

11

我有类似这样的东西

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 => Convert(dest.Product.SelectedProductId”必须解析为顶级成员。参数名称:lambdaExpression。

我不确定该如何处理。


你能修复一下你的代码吗?里面有很多错误。例如,public class MyTest() 不是一个有效的类声明,而 public MyTest() { get; set;} 也不是一个有效的属性声明。 - Daniel T.
你是否有意将视图模型映射回域类?这不被自动映射工具的开发者所推荐。 - Brian Cauthon
2
@Brian - 当然可以啊。我是这么想的,这不是自动映射器的全部意义吗?否则我就得手工制作所有东西,这样就打败了自动映射器的目的。那我还不如也手工将域映射到视图模型。 - chobo2
1
参见此SO问题,关于如何从视图模型映射回域模型。我也不知道为什么你想将产品视图映射到商店。为什么不直接映射回实际的产品呢?这是一个很好的例子,说明为什么自动映射器不能很好地映射回域。每个人都期望它的工作方式不同。从域到视图模型的映射更加直接,因为它们往往没有许多嵌套对象的级别。 - Brian Cauthon
4个回答

25

要映射嵌套结构,只需在MapFrom参数中创建一个新对象。

示例

映射:

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

2
您可以使用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 >());

希望这能帮到您...


1
你遇到的错误是因为在对象图中不能声明多个级别的映射声明。
由于你只发布了一个属性,所以很难给你提供能使其正常工作的代码。一种选择是将你的视图模型属性更改为MyTestTestId,约定将自动识别它。

我添加了一些更多的属性。 - chobo2
还有一件事,我改变了我的代码结构,试图按照约定来绑定数据,但是它并没有起作用。我将SelectedProductId更改为ProductId,将ProductId(在我的领域中)更改为Id。但仍然无法绑定数据。 - chobo2

0

所有rameest在这个问题上给出的正确答案应该会有所帮助: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,因为它已经过时并且很快将不再受支持。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接