首页 > 解决方案 > 如何在 AutoMapper 中映射通用结构类型

问题描述

我想映射MyEntityMyModel. 第一个是由无法修改的 ORM 生成器给出的。当然 AutoMapper 不能在Id<> -> long没有任何映射定义的情况下进行映射。

public class MyEntity
{
  public Id<MyEntity> Id { get; set; }
  public string Name { get; set; }
  public Id<MyFooEntity> FooId { get; set; }
  public Id<MyBarEntity> BarId { get; set; }
}

public class MyModel
{
  public long Id { get; set; }
  public string Name { get; set; }
  public long FooId { get; set; }
  public long BarId { get; set; }
}

public struct Id<T>
{
  private long _internalId { get; set; }
  public long ToLong() => _internalId;
}

什么工作如下:

CreateMap<MyEntity, MyModel>()
  .ForMember(d.Id, o => o.MapFrom(s => s.ToLong())
  .ForMember(d.FooId, o => o.MapFrom(s => s.ToLong())
  .ForMember(d.BarId, o => o.MapFrom(s => s.ToLong());

我在一个实体中有很多实体和几十个 id 属性。我喜欢做的是定义一个通用的结构映射Id<> -> long。但这似乎是不可能的。我试过了TypeConverterITypeConverter<,>还有其他的东西。我得到的最接近的是这个,但是 AutoMapper 投诉Id<>不是引用类型,不能用作System.Object

CreateMap(typeof(Id<>), long).ConvertUsing((s, d) => s.ToLong());

任何建议如何做到这一点?有没有办法像已经存在的那样定义全局映射,比如int -> string, int -> long, ...

标签: c#structautomapper

解决方案


是的,这是可能的。但是你需要修改Id<T>结构。

据我了解,您正在使用一些生成器来生成源文件。MyEntity例如。生成类后,您需要手动修改Id<T>struct. 它应该有一个这样的界面,例如:

public interface IId
{
    long ToLong();
}

public struct Id<T> : IId
{
    private long _internalId { get; set; }
    public long ToLong() => _internalId;
}

现在您可以像这样创建配置,它将映射Id<T>类中的所有类型。

configuration.CreateMap<MyEntity, MyModel>();

configuration.CreateMap<IId, long>()
                .ConvertUsing(x => x.ToLong());

推荐阅读