【问题标题】:Automapper flattening issuesAutomapper 扁平化问题
【发布时间】:2016-04-02 15:52:02
【问题描述】:

我是 Automapper 的新手,所以这可能是一个简单的解决方案,但我在展平对象时遇到了麻烦。例如我有以下数据库调用:

var le = db.LeagueEvents.Include("Venue").Include(p => p.venue.place).ToList();

这是 LeagueEventsVenuePlace 的样子:

public class LeagueEvent
{
    public int EventId { get; set; }
    public string EventTitle { get; set; }
    public Venue venue { get; set; }
}

public class Venue
{
    public string VenueName { get; set; }
    public Place place { get; set; }
}

public class Place
{
    public string address { get; set;}
}

现在,当我直接转换为DailyEvent 的 VM 时,它的映射结果很好

        Mapper.CreateMap<LeagueEvent, LeagueEventViewModelDailies>();
        Mapper.CreateMap<Place, PlaceViewModel>();
        Mapper.CreateMap<Venue, VenueViewModelDailies>();

但是当我尝试使用如下虚拟机将其展平时:

 public class DailyEventVM
{
    public int EventId { get; set; }
    public string EventTitle { get; set; }
    public string VenueName { get; set; }
    public string address { get; set; }
}

我为 VenueNameaddress 返回空值

我需要做类似的事情吗:

.ForMember(dest => dest.VenueName, opts => opts.MapFrom(src => src.Venue.VenueName)

如果是这样,是否有一种“批量”的方式来执行此操作,因为我可以看到它变得相当复杂,需要映射大量字段。

更新 我开始认为它可能与 EF 和代理对象有关。 因为以下工作:

            Mapper.CreateMap<LeagueEvent, LeagueEventViewModelDailies>()
            .ForMember(d => d.Address, opt => opt.ResolveUsing(src => src.venue.place.Address))
            .ForMember(d => d.AptUnit, opt => opt.ResolveUsing(src => src.venue.place.AptUnit))
            .ForMember(d => d.City, opt => opt.ResolveUsing(src => src.venue.place.City))
            .ForMember(d => d.State, opt => opt.ResolveUsing(src => src.venue.place.State))
            .ForMember(d => d.PostalCode, opt => opt.ResolveUsing(src => src.venue.place.PostalCode))
            .ForMember(d => d.Latitude, opt => opt.ResolveUsing(src => src.venue.place.Latitude))
            .ForMember(d => d.Longitude, opt => opt.ResolveUsing(src => src.venue.place.Longitude))
            .ForMember(d => d.VenueName, opt => opt.ResolveUsing(src => src.venue.VenueName))
            .ForMember(d => d.VenueDescription, opt => opt.ResolveUsing(src => src.venue.Description))
            .ForMember(d => d.PrimaryPhone, opt => opt.ResolveUsing(src => src.venue.PrimaryPhone))
            .ForMember(d => d.SecondaryPhone, opt => opt.ResolveUsing(src => src.venue.SecondaryPhone))
            .ForMember(d => d.Link, opt => opt.ResolveUsing(src => src.venue.Link));

这些工作(彼此独立):

lvm = Mapper.Map<Venue, LeagueEventViewModelDailies>(l.venue);
            lvm = Mapper.Map<Place, LeagueEventViewModelDailies>(l.venue.place);

独立使用上述每一项,它们会正确返回场地信息或地点信息。

但是,对于地点和地点,以下内容仍然返回 null:

lvm = Mapper.Map<LeagueEvent, LeagueEventViewModelDailies>(l);

当我深入研究并查看“l”场地和地点是代理对象时,我认为这就是导致空值的原因。

为简洁起见,第一个示例是我正在使用的一个子集。

一如既往地感谢您的帮助,

【问题讨论】:

  • 我现在没有时间构建一个例子,但是看看github.com/AutoMapper/AutoMapper/wiki/Flattening。 '如果对于目标类型上的任何属性,源类型上不存在以“Get”为前缀的属性、方法或方法,AutoMapper 会将目标成员名称拆分为单个单词(通过 PascalCase 约定)。'
  • 感谢您的快速回复。在发布之前我确实看过它,并进一步测试了正在发生的事情是 Venue 对象没有被映射,但 Place 对象是。目前我继续使用 formember 方法,现在它正在工作,但我真的很想了解为什么场地没有完全映射。

标签: automapper flatten


【解决方案1】:

未映射场地名称的原因是其命名不一致。在您的目标类中,它称为VenueName,自动映射器将选择为(src).Venue.Name,但在Venue 类中,该成员称为VenueName

您的选择:

  1. Venue.VenueName 重命名为Venue.Name
  2. DailyEventVM.VenueName 重命名为DailyEventVM.VenueVenueName

使用相同的逻辑,地址属性应称为DailyEventVM.VenuePlaceAddress,Automapper 将在帕斯卡大小写上拆分为(src).Venue.Place.Address

【讨论】:

    【解决方案2】:

    您可以将多个源对象映射到一个目标对象(例如您的 VM 对象),配置起来要容易得多:

    public class Src1
    {
        public string P1 { get; set; }
    }
    
    public class Src2
    {
        public string P2 { get; set; }
    }
    
    public class Dest
    {
        public string P1 { get; set; }
        public string P2 { get; set; }
    }
    

    还有映射:

    Mapper.CreateMap<Src1, Dest>();
    Mapper.CreateMap<Src2, Dest>();
    
    var src1 = new Src1 { P1 = "foo" };
    var src2 = new Src2 { P2 = "bar" };
    var dest = new Dest();
    
    Mapper.Map(src1, dest);
    Mapper.Map(src2, dest);
    
    Assert.AreEqual("foo", dest.P1);
    Assert.AreEqual("bar", dest.P2);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-23
      相关资源
      最近更新 更多