首先,如果我的上述问题令人困惑,我对使用Automapper都不熟悉,并且不太了解这种语言并且很少提出这样的问题,所以我可能会试着说清楚我的问题。想到一个荒谬的问题。
我创建了一些从基类继承的类,因为我打算重新使用基类来实现比下面显示的实体更多的实体。为简单起见,我将保持类的属性无效。
我的问题是PersonBusiness属性的映射。当我使用EF 6从SQL加载数据时,我看到它将PersonBusiness对象的Person和Business属性作为Employee对象和Branch对象加载,因为这是我为查询提取的内容,但是当我尝试映射时Employee Object和Branch对象从PersonBusiness对象到PersonBusinessDto对象,它将它们作为Person和Business类类型加载;显然,不包括派生类中包含的所有属性。
很明显,鉴于加载到PersonBusiness对象中的数据,Person和Business属性是可以使用派生类型Employee和Branch加载的对象引用变量,但出于某种原因,Automapper会看到Employee和Branch对象并且只将它们映射到Person and Business的基本类型。
这是从数据库加载的数据的示例:
这是映射到PersonBusinessDto的数据示例:
下面是我用来将实体映射到DTO的基本类结构和映射,除了PersonBusiness映射之外,它们可以正常工作。
Entity.cs
public abstract class Entity : IEntity
{
}
EntityDto.cs
public abstract class EntityDto : IEntityDto
{
}
Person.cs
public abstract class Person : Entity
{
public List<PersonBusiness> PersonBusinesses { get; set; };
}
PersonDto.cs
public abstract class PersonDto : EntityDto
{
public List<PersonBusinessDto> PersonBusinesses { get; set; };
}
Employee.cs
public class Employee : Person
{
}
EmployeeDto.cs
public class EmployeeDto : PersonDto
{
}
Business.cs
public abstract class Business : Entity
{
public List<PersonBusiness> PersonBusinesses { get; set; };
}
BusinessDto.cs
public abstract class BusinessDto : EntityDto
{
public List<PersonBusinessDto> PersonBusinesses { get; set; };
}
Branch.cs
public class Branch : Business
{
}
BranchDto.cs
public class BranchDto : BusinessDto
{
}
PersonBusiness.cs
public class PersonBusiness
{
public int PersonId { get; set; }
public int BusinessId { get; set; }
public Enums.RoleType RoleType { get; set; }
public Person Person { get; set; }
public Business Business { get; set; }
}
PersonBusinessDto.cs
public class PersonBusinessDto
{
public int PersonId { get; set; }
public int BusinessId { get; set; }
public Enums.RoleType RoleType { get; set; }
public PersonDto Person { get; set; }
public BusinessDto Business { get; set; }
}
AutoMapperConfig.cs
public class ProfileMapping
: Profile
{
private readonly IMapperConfiguration _mappingConfiguration;
public ProfileMapping(IMapperConfiguration config)
{
_mappingConfiguration = config;
}
protected override void Configure()
{
_mappingConfiguration.AllowNullDestinationValues = true;
_mappingConfiguration
.CreateMap<Person, PersonDto>()
.ForMember(dto => dto.PersonBusinesses, opt => opt.MapFrom(src => src.PresonBusinesses));
_mappingConfiguration
.CreateMap<Employee, EmployeeDto>()
_mappingConfiguration
.CreateMap<Business, BusinessDto>()
.ForMember(dto => dto.PersonBusinesses, opt => opt.MapFrom(src => src.PresonBusinesses));
_mappingConfiguration
.CreateMap<Branch, BranchDto>();
_mappingConfiguration
.CreateMap<PersonBusiness, PersonBusinessDto>()
.ForMember(dto => dto.Business, opt => opt.MapFrom(src => src.Business))
.ForMember(dto => dto.Person, opt => opt.MapFrom(src => src.Person));
}
}
答案 0 :(得分:0)
这里发生的事情是,Employee
和Branch
分别被提升为Person
和Business
,因为这些是PersonBusiness
类中的实际类型。然后,当AutoMapper执行映射时,它会看到Person
和Business
类型,因此会根据配置将它们映射到PersonDto
和BusinessDto
。
对象仍然是Employee
和Branch
的实例,即使它们已被上升后也是如此;你可以回到Employee
和Branch
。但是,AutoMapper正在创建PersonDto
和BusinessDto
的实际实例,因此无法将这些实例投射到EmployeDto
和BranchDto
。
如果没有一个具有实际正确属性类型的类,则必须在映射期间将它们转换回正确的类型,这将是一个真正的痛苦。原则上,您将遇到MapFrom
无法返回不同派生类型的问题,因为lambda只能返回一种类型。
AutoMapper提供了一些guidance来说明如何使这种事情发挥作用。但是,您会注意到它直接处理实例,而不是那些实例上的属性。我不确定如何实际执行您需要做的事情,而不是在从PersonBusiness
映射到PersonBusinessDto
时忽略映射这些属性,然后使用方法显式映射属性AutoMapper详细介绍了文档,即
personBusinessDto.Person = Mapper.Map(personBusiness.Person, personBusiness.Person.GetType(), typeof(PersonDto));
像我说的那样:真正的痛苦。