【问题标题】:Automapper configuration setup自动映射器配置设置
【发布时间】:2016-05-02 19:24:49
【问题描述】:

我正在为我的 DAL 使用实体框架,并希望将实体对象转换为业务对象,反之亦然。这发生在我的 BLL 项目中。我希望在我的 BLL 项目中设置 automapper 以采用...假设由 EF 自动生成的 Customer.cs 并将其转换为 CustomerWithDifferentDetail.cs(我的业务 obj)

我尝试使用以下代码在 BLL 项目下创建 AutoMapperBLLConfig.cs:

 public static void Configure()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.AddProfile(new CustomerProfile());
        });
    }


public class CustomerProfile : Profile
{
    protected override void Configure()
    {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<Customer, CustomerWithDifferentDetail>();
            cfg.CreateMap<CustomerWithDifferentDetail, Customer>();
        });
    }
}

然后我在 BLL 项目下创建了 CustermerService.cs 并使用以下代码测试它是否正常工作:

 public void CustomerToCustomerWithDifferentDetail()
 {
     AutoMapperBLLConfiguration.Configure();
     Customer source = new Customer
        {
            Account = 1234,
            Purchase_Quantity = 100,
            Date = "05/05/2016",
            Total = 500
        };

     Models.CustomerWithDifferentDetail testCustomerDTO = Mapper.Map<Customer, Models.CustomerWithDifferentDetail>(source)
 }

我收到此错误: 缺少类型映射配置或不支持的映射。

我不确定我做错了什么。我没有 start_up 或 global.aspx。这是一个类库。我不确定我错过了什么或做错了什么。

我有一个名为 Models 的单独项目,其中包含所有业务对象,包括 CustomerWithDifferentDetail.cs。在这种情况下,CustomerWithDifferentDetail 只有两个属性:Account 和 Total。如果映射,它应该给我 Account = 1234 和 Total = 500 - 与实体对象基本相同的数据只是形状不同。

========================更新======================= ========== AutoMapperBLLConfig.cs - 与上述保持一致

CustomerProfile.cs

public class CustomerProfile : Profile
{
    protected override void Configure()
    {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<Customer, CustomerWithDifferentDetail>().ReverseMap(); //cut it down to one line with ReverseMap
        });
    }
    CreateMap<Customer, CustomerWithDifferentDetail>().ReverseMap(); //missed this one line before; hence, the error
}

客户服务.cs

static CustomerService()
    {
        AutoMapperBLLConfiguration.Configure(); //per @Erik Philips suggestion, move this call to a static constructor 
    }

 public void CustomerToCustomerWithDifferentDetail()
 {
     Customer source = new Customer
        {
            Account = 1234,
            Purchase_Quantity = 100,
            Date = "05/05/2016",
            Total = 500
        };

     Models.CustomerWithDifferentDetail testCustomerDTO = Mapper.Map<Customer, Models.CustomerWithDifferentDetail>(source);
 }

结果:我的 testCustomerDTO 完全符合我的预期。

【问题讨论】:

  • 创建地图后可以放.Reverse()。无需执行第二个“反转”行。
  • 谢谢。我知道这一点。我想知道@James 和 Erik 是否不止一次将其称为映射...
  • 使用 .ForMember 和 .Reverse 时请注意正确映射特定成员。
  • @FernandodeBem 你是什么意思小心?你能详细说明吗?我是新来的。是的,我同时使用 Reverse 和 .ForMember。提前感谢您的提醒。

标签: entity-framework automapper


【解决方案1】:

由于您使用的是 AutoMapper 的实例方法:

var config = new MapperConfiguration(cfg =>
{
  cfg.CreateMap<Customer, CustomerWithDifferentDetail>();
  cfg.CreateMap<CustomerWithDifferentDetail, Customer>();
});

那么你需要使用实例进行映射:

Models.CustomerWithDifferentDetail testCustomerDTO = 
  config.Map<Customer, Models.CustomerWithDifferentDetail>(source)

我个人在我的应用程序中并没有真正考虑到这一点 (I need to move to the instance method instead of the static method)。 (Migrating from status API)。

即兴发挥,根据您的代码,我可能会执行以下操作:

public class PersonDataObject
{
  public string Name { get; set; }
}

public class PersonBusinessObject
{
  private readonly MapperConfiguration _mapper;

  public string Name { get; set; }

  PersonBusinessObject()
  {
    _mapper = new MapperConfiguration(cfg =>
    {
      cfg.CreateMap<PersonDataObject,PersonBusinessObject>();
    });
  }

  public static PersonBusinessObject MapFrom(PersonDataObject data)
  {
    return _mapper.Map<PersonBusinessObject>(data);
  }
}

那么你可以简单地:

PersonDataObject data = new PersonDataObject();

PersonBusinessObject business = PersonBusinessObject.MapFrom(data);

【讨论】:

  • 感谢您的建议。我有个问题。如何从 CustomerService.cs 访问“config”以执行 config.Map(source) ?你是说在我的 CustomerService.cs 类中,我需要创建配置文件的实例吗?至于第二个建议。我喜欢简单地执行 PersonBusinessObject.MapFrom(data) 看起来超级干净整洁,但映射会分散在我的每个业务对象中。我有大量的 obj 要映射。您有什么建议可以将它们分组到一个类似于做个人资料的地方吗?
  • AutoMapper 的作者不建议多次创建地图,这是一个昂贵的过程。相反,静态存储您的 IMapper 实例(从 MapperConfiguration.CreateMapper() 创建)或使用依赖注入,如下所述:stackoverflow.com/questions/36619635/…
  • 正如@James 所说,我的代码只使用静态构造函数创建一次映射。我猜你可以对你的 CustomerService 对象做同样的事情。
  • @ErikPhilips 谢谢。我现在将我的配置调用移动到我的 CustomerService 类的静态构造函数。我也设法解决了这个错误。结果我错过了这一行: CreateMap().ReverseMap();我会在几分钟内更新我的帖子。如果您有任何反馈,我会喜欢更多。我是新手,想正确实施。
猜你喜欢
  • 2012-07-28
  • 1970-01-01
  • 2019-08-10
  • 1970-01-01
  • 1970-01-01
  • 2014-11-19
  • 2019-03-16
  • 2012-08-10
  • 1970-01-01
相关资源
最近更新 更多