【问题标题】:Unable to use Auto Mapper with .net core 2.2无法将 Auto Mapper 与 .net core 2.2 一起使用
【发布时间】:2019-09-05 15:47:08
【问题描述】:

我无法在 .net core 2.2 中使用 Auto Mapper。它一直在抛出这个错误:

找到未映射的成员。查看下面的类型和成员。添加一个 自定义映射表达式,忽略,添加自定义解析器,或修改 源/目标类型对于没有匹配的构造函数,添加一个无参数 ctor,添加可选参数,或映射所有构造函数参数 ==================================================== ==================================================== ==================================================== =================================================== AutoMapper为您创建了此类型映射,但您的类型不能 使用当前配置映射。 IDataReader -> List1 (Destination member list) System.Data.IDataReader -> System.Collections.Generic.List1[[Models.EngineModel, 模型,版本=1.0.0.0,文化=中性, PublicKeyToken=null]](目标成员列表)

未映射的属性:容量

这是我的 EngineModel 类:

public class EngineModel
{
        public string Id { get; set; }

        public int engineNo { get; set; }

        public string engineHost { get; set; }
}

这是我的个人资料:

    public class EngineMappingProfile : Profile
    {
        public EngineMappingProfile()
        {

            CreateMap<IDataReader, EngineModel>()
               .ForMember(dest => dest.Id , opt => opt.MapFrom(src => src.GetString(src.GetOrdinal("ID"))))
               .ForMember(dest => dest.engineNo , opt => opt.MapFrom(src => src.GetInt32(src.GetOrdinal("ENG_NO"))))
               .ForMember(dest => dest.engineHost , opt => opt.MapFrom(src => src.GetString(src.GetOrdinal("ENG_HOST"))))

        }
    }

这是我的 Startup.cs ConfigureServices 方法:


       public void ConfigureServices(IServiceCollection services)
        {

            Mapper.Initialize(cfg =>
            {
                cfg.AddProfile<EngineMappingProfile>();
            });
            services.AddAutoMapper();

            services.AddMvc()
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
                .AddJsonOptions(options =>
                {
                    options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
                });
        }

以上所有代码都在我的 API 项目中。我在我的商业项目中使用这些配置文件:


 var enginesData = AutoMapper.Mapper.Map<IDataReader, List<EngineModel>>(dataReader.mcDataReader);

我正在使用“AutoMapper.Extensions.Microsoft.DependencyInjection (6.0.0)”和“AutoMapper (8.0.0)”

【问题讨论】:

  • 您可能缺少个人资料。您显示了用于映射 IDataReader -> EngineModel 的配置文件,但您实际上是在尝试映射 IDataReader -> List&lt;EngineModel&gt;
  • 它曾经在.net框架中没有任何问题

标签: c# asp.net-core .net-core automapper


【解决方案1】:

您只需要从 NuGet 包安装 AutoMapper.Data(在您的情况下为 3.0.0),然后在启动时添加以下代码:

services.AddAutoMapper(cfg =>
{
    cfg.AddDataReaderMapping();
});

参考

Automapper Map DataTable to POCO list

https://github.com/AutoMapper/AutoMapper.Extensions.Microsoft.DependencyInjection/issues/50

【讨论】:

  • 是的,我想通了。此外,应该在映射中使用 IDataRecord 而不是 IDataReader:CreateMap()
【解决方案2】:

AutoMapper 抱怨是因为 IDataReader 具有您未指定的其他属性。您要么需要将它们全部映射(在这种情况下显然不需要),要么指定它们应该被忽略,例如:

        CreateMap<IDataReader, EngineModel>()
           .ForMember(...)
           .ForMember(...)
           .ForMember(...)
           .ForAllOtherMembers(x => x.Ignore()); // < -- Add this line

【讨论】:

  • 同样的错误。即使我添加了这个,但班上没有其他成员。所有成员都已映射。我注意到另一件事,即使我没有在 startup.cs 中提供该配置文件。它给了我同样的错误。
【解决方案3】:

我使用的版本和你的一样,所以这就是我设置自动映射器的方式

在我的 startup.cs 我只需要这个

services.AddAutoMapper(config => config.ValidateInlineMaps = false);

以及我如何创建 Profile 类

public class CommentProfile : Profile
{
    public CommentProfile()
    {
        CreateMap<Comment, CommentDto>(MemberList.None).ReverseMap();
    }
}

public class Comment : BaseEntity
{
    public string Content { get; set; }
    public virtual Comment ParentComment { get; set; }
    public virtual Post Post { get; set; }
    public virtual User? User { get; set; }
    public CommentStatus CommentStatus { get; set; }
}

public class CommentDto
{
    public int Id { get; set; }
    public Guid UniqeId { get; set; }
    public string Content { get; set; }
    public Comment ParentComment { get; set; }
    public CommentStatus CommentStatus { get; set; }
    public DateTime DateCreated { get; set; }
}

【讨论】:

  • 将其添加到 services.AddAutoMapper 会引发相同的错误。但如果我这样做,它不会抛出任何错误,但也没有任何东西被映射。 code Mapper.Initialize(cfg => { cfg.AddProfile(); }); services.AddAutoMapper(); code
【解决方案4】:

您只需要:

services.AddAutoMapper();

这会在服务集合中注册IMapper,并自动应用命名空间中的所有配置文件(任何继承自Profile 的类)。

那么,您应该注入IMapper,而不是使用静态Mapper。在您的控制器中:

public class MyController : Controller
{
    private readonly IMapper _mapper;

    public MyController(IMapper mapper)
    {
        _mapper = mapper;
    }

然后,当你想映射一些东西时:

 var enginesData = _mapper.Map<List<EngineModel>>(dataReader.mcDataReader);

但是,您不能直接将 IDataReader 实例映射到列表,这是您的主要问题。您需要枚举将行存储为列表中的项目的数据读取器,然后您可以从该列表映射到您的List&lt;EngineModel&gt;。不过,此时将行读取为EngineModel 并在枚举数据读取器时构建列表可能更有意义。那么就完全不需要映射了。

【讨论】:

  • 这曾经在 .net framework Web API 中运行良好。循环遍历数据读取器并一次映射单行会非常低效
  • @Imran Khan 我会使用ProjectTo - 所以var enginesData = _mapper.ProjectTo&lt;EngineModel&gt;(dataReader.mcDataReader);
  • 您认为 AutoMapper 会做什么?同样的事情。
猜你喜欢
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 2017-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-14
  • 2020-02-05
相关资源
最近更新 更多