【发布时间】:2021-07-26 06:49:57
【问题描述】:
我正在努力弄清楚如何使用 AutoMapper 正确地将具有继承的 EF 核心对象映射到 DTO。我正在寻找的正确结果是一个 DTO,它有一个培训和所有为其注册的员工:
以下是三个类:
public class Training
{
public Guid Id { get; set; }
public string Host { get; set; }
public string Name { get; set; }
public ICollection<EmployeeTraining> EmployeeTrainings { get; }
}
public class Employee
{
public Guid Id { get; set; }
public string Designation { get; set; }
public ICollection<EmployeeTraining> EmployeeTrainings { get; }
}
public class EmployeeTraining
{
public Guid EmployeeId {get; set;}
public Employee Employee { get; set; }
public Guid TrainingId { get; set; }
public Training Training{ get; set; }
}
public class TrainingDTO
{
public string Host { get; set; }
public string Name { get; set; }
public ICollection<EmployeeTraining> EmployeeTrainings { get; }
}
AutoMapper 配置文件:
public class TrainingProfile: Profile
{
public TrainingProfile()
{
CreateMap<Training, TrainingDto>()
.ForMember(entity => entity.EmployeeTrainings, opt => opt.MapFrom(model => model));
CreateMap<TrainingDto, Training>();
}
}
代码编译,但运行时我得到:
[2021-05-03T21:21:49.201Z] Exception: Error mapping types.
[2021-05-03T21:21:49.203Z] Mapping types:
[2021-05-03T21:21:49.204Z] Training -> TrainingDto
[2021-05-03T21:21:49.208Z] AzITSSMaster.API.Entities.Training -> AzITSSMaster.API.Models.TrainingDto
[2021-05-03T21:21:49.209Z] Type Map configuration:
[2021-05-03T21:21:49.209Z] Training -> TrainingDto
[2021-05-03T21:21:49.211Z] AzITSSMaster.API.Entities.Training -> AzITSSMaster.API.Models.TrainingDto
[2021-05-03T21:21:49.212Z] Destination Member:
[2021-05-03T21:21:49.212Z] EmployeeTrainings
测试
[Fact]
public void Test1()
{
Guid trainingOneGuid = new Guid("5b1c2b4e48c7402a80c3cc796ad49c6b");
Guid trainingTwoGuid = new Guid("d8663e5f74944f8187396e0de1bea7ee");
Guid employeeOneGuid = new Guid("5b1c2b4d48c7402a80c3cc796ad49c6b");
Guid employeeTwoGuid = new Guid("d8663e5e74944f8187396e0de1bea7ee");
//Create In Memory Database
var options = new DbContextOptionsBuilder<ITSSAPIContext>()
.UseInMemoryDatabase(databaseName: "ITSSMaster")
.Options;
using (var context = new ITSSAPIContext(options))
{
TrainingRepository trepo = new TrainingRepository(context);
EmployeeRepository erepo = new EmployeeRepository(context);
EmployeeTrainingRepository etrepo = new EmployeeTrainingRepository(context);
// Create
trepo.Create(new Training
{
Id = trainingOneGuid,
Host = "ATS",
Name = "ATS Test Training 1",
StartDate = DateTime.Now,
Facillitator = "Darth Maul",
StipendAmount = 750,
});
trepo.Create(new Training
{
Id = trainingTwoGuid,
Host = "CO",
Name = "CO Test Training 1",
StartDate = DateTime.Now,
Facillitator = "Darth Vader",
StipendAmount = 0
});
erepo.Create(new Employee
{
Id = Guid.Parse("5b1c2b4d-48c7-402a-80c3-cc796ad49c6b"),
OrgDefinedId = 000032615,
Designation = String.Empty
});
erepo.Create(new Employee
{
Id = Guid.Parse("d8663e5e-7494-4f81-8739-6e0de1bea7ee"),
OrgDefinedId = 000012345,
Designation = "Champion"
});
//Training: GetIncluding
Training training1 = trepo.GetIncluding<Training>(
trainingOneGuid,
c => c.EmployeeTrainings);
Assert.Equal("ATS Test Training 1", training1.Name);
Training training2 = trepo.GetIncluding<Training>(
trainingTwoGuid,
c => c.EmployeeTrainings);
Assert.Equal("CO Test Training 1", training2.Name);
//Employee: GetIncluding
Employee employee1 = erepo.GetIncluding<Employee>(
employeeOneGuid,
c => c.EmployeeTrainings);
Assert.Equal(000032615, employee1.OrgDefinedId);
Employee employee2 = erepo.GetIncluding<Employee>(
employeeTwoGuid,
c => c.EmployeeTrainings);
Assert.Equal(000012345, employee2.OrgDefinedId);
//EmployeeTraining: Add
etrepo.AddTrainingToEmployee(employee1, training1);
etrepo.AddTrainingToEmployee(employee2, training1);
Assert.Equal(2, training1.EmployeeTrainings.Count);
etrepo.AddTrainingToEmployee(employee1, training2);
Assert.Equal(1, training2.EmployeeTrainings.Count);
Assert.Equal(2, employee1.EmployeeTrainings.Count);
Assert.Equal(1, employee2.EmployeeTrainings.Count);
//Automapper
var config1 = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Training, TrainingDto>()
.ForMember(dst => dst.EmployeeTrainings,
opt => opt.MapFrom(model => model.EmployeeTrainings));
});
//Using automapper
var mapper1 = new Mapper(config1);
var TrainingDto1 = mapper1.Map<TrainingDto>(training1);
var TrainingDto2 = mapper1.Map<TrainingDto>(training2);
}
}
观察窗口
【问题讨论】:
标签: c# entity-framework-core automapper