C# 使用AutoMapper从实体映射到DTO或DTO映射到实体时出错

C# 使用AutoMapper从实体映射到DTO或DTO映射到实体时出错,c#,entity-framework,automapper,C#,Entity Framework,Automapper,我使用EntityFramework作为数据层,使用DTO在层之间传输数据。我在N层体系结构中开发Windows窗体,当我尝试在BLL中从实体映射到DTO时: public IEnumerable<CategoryDTO> GetCategoriesPaged(int skip, int take, string name) { var categories = unitOfWork.CategoryRepository.GetCategoriesPaged(skip, ta

我使用EntityFramework作为数据层,使用DTO在层之间传输数据。我在N层体系结构中开发Windows窗体,当我尝试在BLL中从实体映射到DTO时:

public IEnumerable<CategoryDTO> GetCategoriesPaged(int skip, int take, string name)
{
    var categories = unitOfWork.CategoryRepository.GetCategoriesPaged(skip, take, name);
    var categoriesDTO = Mapper.Map<IEnumerable<Category>, List<CategoryDTO>>(categories);

    return categoriesDTO;
}
并且自动映射配置在BLL中:

public class AutoMapperBusinessConfiguration
{
    public static void Configure()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.AddProfile<EntityToDTOProfile>();
            cfg.AddProfile<DTOToEntityProfile>();
        });
    }
}

public class EntityToDTOProfile : Profile
{
    public override string ProfileName
    {
        get { return "EntityToDTOMappings"; }
    }

    protected override void Configure()
    {
        Mapper.CreateMap<Category, CategoryDTO>();
    }
}

public class DTOToEntityProfile : Profile
{
    public override string ProfileName
    {
        get { return "DTOToEntityMappings"; }
    }

    protected override void Configure()
    {
        Mapper.CreateMap<CategoryDTO, Category>();
    }
}
公共类自动映射业务配置
{
公共静态void Configure()
{
Mapper.Initialize(cfg=>
{
AddProfile();
AddProfile();
});
}
}
公共类EntityToToToProfile:配置文件
{
公共重写字符串配置文件名
{
获取{return“EntityToToMappings”;}
}
受保护的覆盖无效配置()
{
CreateMap();
}
}
公共类DTOToEntityProfile:配置文件
{
公共重写字符串配置文件名
{
获取{return“DTOToEntityMappings”;}
}
受保护的覆盖无效配置()
{
CreateMap();
}
}
当从DTO映射到实体时,我也遇到了同样的错误

category = Mapper.Map<Category>(categoryDTO);
category=Mapper.Map(categoryDTO);

如何解决此问题?

在调用
Configure()
后使用
AutoMapper.assertconfigurationsvalid()
。如果任何操作失败,它将抛出一个带有描述性文本的异常。它应该为您提供更多信息,以便进一步调试。

这是因为您正在使用
映射器。多次初始化
。如果查看它调用
Mapper.Reset()
的源代码,这意味着只有最后定义的映射才能工作。因此,只需删除初始化调用并替换为使用AutoMapper和EntityFramework将DTO映射到实体

这里我们有一个实体类Country和一个CountryDTO

 public class Country
 {
     public int CountryID { get; set; }
     public string ContryName { get; set; }
     public string CountryCode { get; set; }
 }
CountryDTO collection=new CountryDTO();
 collection.CountryID =1;
 collection.ContryName ="India";
 collection.CountryCode ="in";

Country model = Convertor.Convert<Country, CountryDTO>(collection);
dbcontext.Countries.Add(model);
dbcontext.SaveChanges();
CountryDto

 public class CountryDTO
{
   public int CountryID { get; set; }
   public string ContryName { get; set; }
   public string CountryCode { get; set; }
}
创建CountryDTO的对象

 public class Country
 {
     public int CountryID { get; set; }
     public string ContryName { get; set; }
     public string CountryCode { get; set; }
 }
CountryDTO collection=new CountryDTO();
 collection.CountryID =1;
 collection.ContryName ="India";
 collection.CountryCode ="in";

Country model = Convertor.Convert<Country, CountryDTO>(collection);
dbcontext.Countries.Add(model);
dbcontext.SaveChanges();
CountryDTO collection=newcountrydto();
collection.CountryID=1;
collection.controlyname=“印度”;
collection.CountryCode=“in”;
国家/地区模型=转换器。转换(收集);
dbcontext.Countries.Add(模型);
dbcontext.SaveChanges();
这对于一个新的国家来说很好,上面的代码将CountryDTO映射到Country实体对象,并将新实体添加到dbcontext中并保存更改

using System.Reflection;
public static TOut Convert<TOut, TIn>(TIn fromRecord) where TOut : new()
 {
  var toRecord = new TOut();
  PropertyInfo[] fromFields = null;
  PropertyInfo[] toFields = null;

  fromFields = typeof(TIn).GetProperties();
  toFields = typeof(TOut).GetProperties();

  foreach (var fromField in fromFields)
   {
    foreach (var toField in toFields)
      {
        if (fromField.Name == toField.Name)
          {
             toField.SetValue(toRecord, fromField.GetValue(fromRecord, null), null);
            break;
          }
      }

  }
return toRecord;
}

public static List<TOut> Convert<TOut, TIn>(List<TIn> fromRecordList) where TOut : new()
 {
  return fromRecordList.Count == 0 ? null : fromRecordList.Select(Convert<TOut, TIn>).ToList();
 }
使用系统反射;
公共静态TOut转换(TIn fromRecord),其中TOut:new()
{
var toRecord=newtout();
PropertyInfo[]fromFields=null;
PropertyInfo[]toFields=null;
fromFields=typeof(TIn).GetProperties();
toFields=typeof(TOut).GetProperties();
foreach(fromFields中的var fromField)
{
foreach(toFields中的var toField)
{
if(fromField.Name==toField.Name)
{
toField.SetValue(toRecord,fromField.GetValue(fromRecord,null),null);
打破
}
}
}
返回记录;
}
公共静态列表转换(来自记录列表的列表),其中TOut:new()
{
return fromRecordList.Count==0?null:fromRecordList.Select(Convert).ToList();
}

而不是
var categoriesDTO=Mapper.Map(categories)
您是否可以尝试使用
var categoryDto=Mapper.Map(category)
在一个循环中一次映射它们一个?@wal我遇到了相同的错误“缺少类型映射配置或不支持的映射”,而不是使用配置文件。如果您尝试在实际映射之前创建映射,您可以看到会发生什么。例如调用
Mapper.CreateMap()然后直接完成映射;不要映射从实体框架返回的列表;我删除了这个概要文件,在执行Mapper.map之前定义了Mapper.CreateMap(),它就可以工作了。我想是因为使用配置文件的配置没有正确配置。实际上,我想集中自动映射配置,所以我使用的是profile。你知道如何在更高的体系结构中实现这一点吗?这是因为你使用的是
Mapper.Initialize
multipe times。如果查看此调用的源代码,它将调用
Mapper.Reset()
,这意味着只有最后定义的映射才能工作。因此,只需删除
Initialize
调用并替换为Mapper.AddProfile<>Nice info,在调用assertconfigurationsvalid()之后,会有一些异常映射,非常具有描述性。谢谢