简体   繁体   English

使用接口将实体映射到dto

[英]Mapping entity to dto with interfaces

I've my entity class I retrieve from database: 我有从数据库检索的实体类:

public class User{
    public string Username {get; set;}
    public List<IAddress> Addresses {get; set;}
}

public class Address: IAddress{
    public string Line1 {get; set;}
    public string Line2 {get; set;}
}
public class AddressExtended:Address, IAddress{
    public string Line3 {get; set;}
    public string Line4 {get; set;}
}
public interface IAddress{
}

I use Automapper to map this entity to the mirrored DTO: 我使用Automapper将此实体Automapper到镜像的DTO:

public class UserDto{
    [JsonProperty("username")]
    public string Username { get; set; }
    [JsonProperty("addresses")]
    public List<IAddressDto> Addresses { get; set; }
}

public class AddressDto: IAddressDto{
    [JsonProperty("line1")]
    public string Line1 { get; set; }
    [JsonProperty("line2")]
    public string Line2 { get; set; }
}
public class AddressExtendedDto:AddressDto, IAddressDto{
    [JsonProperty("line3")]
    public string Line3 { get; set; }
    [JsonProperty("line4")]
    public string Line4 { get; set; }
}
public interface IAddressDto{
}

Automapper configuration is the following: 自动映射器的配置如下:

CreateMap<IAddress, IAddressDto>();
CreateMap<Address, AddressDto>();
CreateMap<AddressExtended, AddressExtendedDto>();

The problem is that when I run my application, if in the entity I have 2 addresses and 1 addressExtended, in DTO the Addresses property () is mapped like this: 问题是,当我运行应用程序时,如果在实体中我有2个地址和1个AddressExtended,则在DTO中,Addresses属性()的映射如下:

[   
 {Proxy<MyProject.Models.Dto.IAddressDto_MyProject_Version=1.0.0.0_Culture=neutral_PublicKeyToken=null>},
 {Proxy<MyProject.Models.Dto.IAddressDto_MyProject_Version=1.0.0.0_Culture=neutral_PublicKeyToken=null>},
 {Proxy<MyProject.Models.Dto.IAddressDto_MyProject_Version=1.0.0.0_Culture=neutral_PublicKeyToken=null>}
]

The Username property it is correctly valued. 正确设置了Username属性。

What I miss? 我想念什么?

UPDATE UPDATE

I added a fiddler here: 我在这里添加了一个提琴手:

https://dotnetfiddle.net/ZkUZgp https://dotnetfiddle.net/ZkUZgp

As per my knowledge, one approach solving the issue is using Construct using below code 据我所知,解决该问题的一种方法是使用以下代码构建

cfg.CreateMap<Address, AddressDto>();
cfg.CreateMap<AddressExtended, AddressExtendedDto>();
cfg.CreateMap<IAddress, IAddressDto>().ConstructUsing((IAddress addressDto) =>
{
    if (addressDto is AddressExtended) return Mapper.Map<AddressExtendedDto>(addressDto);
    return Mapper.Map<AddressDto>(addressDto);
});

Edit 1: Here is the final answer and it solves your problem 编辑1:这是最终答案,它可以解决您的问题

cfg.CreateMap<Address, AddressDto>();
cfg.CreateMap<AddressExtended, AddressExtendedDto>();
cfg.CreateMap<IAddress, IAddressDto>().ConstructUsing((addressDto, ctx) =>
{
    var destination = Mapper.Instance.ConfigurationProvider.GetAllTypeMaps()
                        .First(t => t.SourceType == addressDto.GetType());
    return ctx.Mapper.Map(addressDto, addressDto.GetType(), destination.DestinationType) as IAddressDto;
});

Instead of getting destination type using LINQ you can build a dictionary and get from it for faster execution. 无需使用LINQ获取目标类型,您可以构建字典并从中获取字典以更快地执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM