.net AutoMapper ForMember方法破坏了Map功能

eqqqjvef  于 2022-12-20  发布在  .NET
关注(0)|答案(1)|浏览(142)

我想在我的.Net 6 API中使用AutoMapper将实体模型User转换为DTO模型UserDTO
User模型类为:

public class User : BaseEntity
{
  public Guid Id { get; set; }
  public string FirstName { get; set; } = null!;
  public string LastName { get; set; } = null!;
  public string Avatar { get; set; } = null!;
  public string Email { get; set; } = null!;
  public ICollection<Book>? FavoriteBooks { get; set; }
}

并且UserDTO是如下的记录:

public record UserDTO(Guid Id, string FullName, string Avatar, string Email);

我已经添加了所需的包AutoMapper.Extensions.Microsoft.DependencyInjection v.12.0.0,配置步骤如下:
1-创建从Profile类继承的MappingProfile

public class MappingProfiles : Profile
{
  public MappingProfiles()
  {
    CreateMap<User, UserDTO>()
      .ForMember(
          dest => dest.FullName,
          opt => opt.MapFrom(src => string.Join(" ", src.FirstName, src.LastName))
      );
  }
}

2-在Program.cs文件中注册服务:

builder.Services.AddAutoMapper(typeof(Program));

3-将Map器用作Service项目中的注入服务:

public IEnumerable<UserDTO> GetAllUsers(bool trackChanges)
{
   var users = _repository.User.GetAllUsers(trackChanges);
   return _mapper.Map<IEnumerable<UserDTO>>(users);
}

当我在postman中调用GetAllUsers方法时,我得到以下错误:
Map类型时出错。
Map类型:
列表-〉可枚举
经过几天的努力和搜索,我意识到.ForMember()方法破坏了profile类的功能,换句话说,如果我更改UserDTO记录:

public record UserDTO(Guid Id, string FirsName, string Avatar, string Email);

FullName文件更改为FirstName以与User型号兼容。同时更改MappingProfile类:

public class MappingProfiles : Profile
{
  public MappingProfiles()
  {
    CreateMap<User, UserDTO>();
  }
}

GetAllUsers方法按预期工作。因此,总结一下,如果我像文档中那样将.ForMember()方法添加到MappingProfile类的构造函数中,它将破坏CreatMap方法的功能。
如何使用.ForMember()方法将User模型Map到相应的DTO?此方法是否已过时?是否有替代方法?

7xllpg7q

7xllpg7q1#

我找到了两个解决方案:

解决方案1:

我创建了一个方法来获取用户的全名。方法名应该以get为前缀:
命名约定可以涵盖更简单的示例,其中源对象具有属性、方法或以“Get”作为前缀的方法,并且该属性、方法或方法与目标对象的属性同名。
因此我修改了User模型类并添加了以下方法:

public class User : BaseEntity
{
    ... // User model properties
    public string GetFullName() => $"{this.FirstName} {this.LastName}";
}

并从配置文件类中删除了.ForMemeber()'方法:

public MappingProfiles()
{
    CreateMap<User, UserDTO>();
}

解决方案2:

看起来.ForMember()已经过时了,我已经找到了一个替代品,.ForCtorParam()

public MappingProfiles()
{
    CreateMap<User, UserDTO>()
      .ForCtorParam(
          "FullName",
          opt => opt.MapFrom(src => string.Join(" ", src.FirstName, src.LastName))
      );
}

通过这些方法,我已经将User模型类转换为UserDTO

相关问题