当源包含导航属性时,自动映射器会丢失值

问题描述

版本:

ASP.NET Core 3.1
AutoMapper 10.0.0
EF Core 3.1.6

我的实体:

public class Room
{
    [Key]
    public int Id { get; set; }

    // not equal to 'RoomDetail.StdSectionId',// this is custom section id,ex. MyFrance
    public int SectionId { get; set; }
    public virtual Section Section { get; set; }

    public string displayName { get; set; }
}

public class RoomDetail
{
    [Key]
    public int Id { get; set; }

    public int RoomId { get; set; }
    public Room Room { get; set; }

    // not equal to 'Room.SectionId',// this is origin section,ex: France
    [ForeignKey("Section")]
    public int StdSectionId { get; set; }  
    public virtual Section Section { get; set; }

    public int Floor { get; set; }
}

我的DTO:

public class RoomDetailDTO
{
    public int RoomId { get; set; }

    public int Floor { get; set; }

    public int SectionId { get; set; }

    public int StdSectionId { get; set; }
}

我有以下代码

// Mapping configuration
CreateMap<Room,RoomDetailDTO>();
CreateMap<RoomDetail,RoomDetailDTO>();

// Controller
var query = (from room in _context.Room 
            join roomDetail in _context.RoomDetail on room.Id equals roomDetail.RoomId
            where room.Id.Equals(4)
            select new { room,roomDetail }).AsNoTracking().AsEnumerable();

var roomInfo = query.First();
// roomInfo = 
// {
//     "room": {
//         "id": 4,//         "sectionId": 15,//         "section": null,//         "displayName": "MyRoom"
//     },//     "roomDetail": {
//         "id": 9,//         "roomId": 4,//         "room": null,//         "stdSectionId": 1,//         "floor": 2
//     },// }
var dto = _mapper.Map<RoomDetailDTO>(roomInfo.room);
_mapper.Map(roomInfo.roomDetail,dto);

预期:

dto = {
    "roomId": 4,"floor": 2,"sectionId": 15,"stdSectionId": 1,}

但是实际行为:

dto = {
    "roomId": 4,"sectionId": 0,}

问题在于,RoomDetailDTO.SectionId在映射后为零。 我试图从Section删除导航属性RoomDetail。这行得通。 RoomDetailDTO.SectionId被映射。 但是有时我需要使用navigation属性,因此无法删除它。

我试图忽略导航属性,但不起作用:

public static IMappingExpression<TSource,TDestination> IgnoreAllVirtual<TSource,TDestination>(this IMappingExpression<TSource,TDestination> expression)
{
    var desType = typeof(TDestination);
    foreach (var property in desType.GetProperties().Where(p => p.Getgetmethod().IsVirtual))
    {
        expression.ForMember(property.Name,opt => opt.Ignore());
    }

    var srcType = typeof(TSource);
    foreach (var property in srcType.GetProperties().Where(p => p.Getgetmethod().IsVirtual))
    {
        expression.ForSourceMember(property.Name,opt => opt.DoNotValidate());
    }

    return expression;
}

我不太了解AutoMapper代码在做什么,因此很难调试。 如果有人能解释mapper如何用于导航属性,那将是很好的。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)