Automapper,CustomMapping未加载虚拟属性的字段

本文关键字:属性 字段 虚拟 加载 CustomMapping Automapper | 更新日期: 2023-09-27 17:57:57

我有以下类。

 public class SomeModel
        {
            [Key]
            public int Id { get; set; }
            [Required]
            public string UserId { get; set; }
            public virtual User User { get; set; }
            [Required]
            public string Name { get; set; }  
        }

和:

public class SomeModelDetailsResponseModel : IMapFrom<SomeModel>, IHaveCustomMappings
    {
        public int Id { get; set; }
        public string UserId { get; set; }
        public string Name { get; set; }
        public string UserName { get; set; }
        public void CreateMappings(IConfiguration configuration)
        {
            configuration.CreateMap<SomeModel, SomeModelDetailsResponseModel>("name").AfterMap((b, r) =>
            {
                r.UserName = b.User.FirstName + b.User.LastName;
            });
        }
    }

出于某种原因,当我将SomeModelIQueryable投影到SomeModelDetailsResponseModelIQueryable时,UserName属性变成了null

Automapper,CustomMapping未加载虚拟属性的字段

假设这些是类定义:

public class User
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
public class SomeModel
{
    public int Id { get; set; }
    public string UserId { get; set; }
    public virtual User User { get; set; }
    public string Name { get; set; }
}
public class SomeModelDetailsResponseModel
{
    public int Id { get; set; }
    public string UserId { get; set; }
    public string Name { get; set; }
    public string UserName { get; set; }
}

解决方案1

你的地图是这样的吗:

var config = new MapperConfiguration(
    cfg =>
    {
        cfg.CreateMap<SomeModel, SomeModelDetailsResponseModel>().AfterMap((b, r) =>
        {
            r.UserName = b.User.FirstName + b.User.LastName;
        });
     });
var mapper = config.CreateMapper();
var response = mapper.Map<SomeModel, SomeModelDetailsResponseModel>(new SomeModel()
{
    User = new User()
    {
        FirstName = "FN",
        LastName = "LN"
    }
});

既然你的输入是IQueryable<SomeModel>,并且你想把它投影到IQueryable<SomeModelDetailsResponseModel>中,那么你可以这样做:

var result = q.Select(m => mapper.Map<SomeModel, SomeModelDetailsResponseModel>(m));

其中q是您的IQueryable<SomeModel>实例。

解决方案2

如果您想使用ProjectTo<>,请按照以下方式初始化映射器:

Mapper.Initialize(cfg =>
{
    cfg.CreateMap<SomeModel, SomeModelDetailsResponseModel>()
        .ForMember(r => r.UserName, c => c.MapFrom(o => o.User.FirstName + o.User.LastName));
});

然后,按以下方式进行投影:

var result = q.ProjectTo<SomeModelDetailsResponseModel>().ToArray();

其中q是您的IQueryable<SomeModel>