使用AutoMapper将实体映射到DTO或DTO映射到实体时出现错误

6

我正在使用EntityFramework作为数据层,并使用DTO在层之间传输数据。我在N-Tier架构中开发Windows Forms,当我尝试在BLL中从Entity映射到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;
}

我遇到了这个错误: http://s810.photobucket.com/user/sky3913/media/AutoMapperError.png.html 错误提示我缺少类型映射配置或不支持的映射。我已经在UI层使用配置文件注册映射,方式如下:
[STAThread]
static void Main()
{
    AutoMapperBusinessConfiguration.Configure();
    AutoMapperWindowsConfiguration.Configure();
    ...
    Application.Run(new frmMain());
}

而AutoMapper的配置在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>();
    }
}

当从DTO映射到Entity时,我也遇到了相同的错误。

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

如何解决这个问题?

你能否尝试使用循环一个一个地映射它们,而不是使用 var categoriesDTO = Mapper.Map<IEnumerable<Category>, List<CategoryDTO>>(categories); 这种方式进行映射呢?使用 var categoryDto = Mapper.Map<CategoryDTO>(category) - wal
你尝试过使用Mapper.AddProfile(new EntityToDTOProfile())而不是Mapper.Initialize吗?从源代码来看应该没有问题,但还是试一下。同时确保在启动应用程序时能够访问到你的映射配置文件。 - wal
@wal 我已经更改了Mapper.Initialize并尝试了Mapper.AddProfile(new EntityToDTOProfile()),结果是相同的。 - Willy
@wal 是的,它被正确地调用了。我想我找到了问题所在,在调用 AutoMapperBusinessConfiguration.Configure(); 之后,我从 DTO 到 ViewModel 调用了映射配置 AutoMapperWindowsConfiguration.Configure();。如果我删除 AutoMapperWindowsConfiguration.Configure(); 它就可以工作了。那么,我应该在一个类中定义它,还是有一种根据其功能在不同类中配置的方法? - Willy
1
这是因为您多次使用了 Mapper.Initialize。如果您查看此调用的源代码,它会调用 Mapper.Reset(),这意味着只有最后一个定义的映射会起作用。因此,请简单地删除 Initialize 调用,并替换为 Mapper.AddProfile< > - wal
显示剩余6条评论
3个回答

4

这是因为您多次使用了 Mapper.Initialize。如果查看源代码,它会调用 Mapper.Reset(),这意味着只有最后一个定义的映射将起作用。所以,您可以简单地删除 Initialize 调用,并用 Mapper.AddProfile< > 替换。


2
在调用Configure()后使用AutoMapper.AssertConfigurationIsValid()。如果出现任何问题,它将抛出带有描述性文本的异常。这应该会给您更多的信息来进一步调试。

很好的信息,调用AssertConfigurationIsValid()后有一些映射异常,非常详细。谢谢。 - Willy

1

使用AutoMapper和EntityFramework将DTO映射到实体

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

 public class Country
 {
     public int CountryID { get; set; }
     public string ContryName { get; set; }
     public string CountryCode { get; set; }
 }

CountryDto
 public class CountryDTO
{
   public int CountryID { get; set; }
   public string ContryName { get; set; }
   public string CountryCode { get; set; }
}

创建 CountryDTO 对象。
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映射到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();
 }

http://bhupendrasinghsaini.blogspot.in/2014/09/convert-enity-framwork-data-in-entity.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接