自动化扁平化问题

时间:2015-12-28 19:35:22

标签: automapper flatten

我是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的虚拟机时,它会很好地映射

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

但是当我尝试使用像:

这样的vm来展平它时
 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)

如果有,那么&#34;批量&#34;这样做的方式是因为我可以看到它变得非常复杂,需要映射大量字段。

更新 我开始认为它可能与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);

当我钻进并查看&#34; l&#34;场地和地点是代理对象,我认为这是导致空值的原因。

第一个例子是我为简洁起见而工作的一部分。

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

2 个答案:

答案 0 :(得分:1)

未映射场地名称的原因是它没有一致地命名。在您的目标类中,它被称为angular.module('app', []).controller("controllername", ["$scope", function($scope) { $scope.getLanguages = [ {"en":"English"}, {"fr":"French"} ]; $scope.getKey = function(getLanguages) { return Object.keys(getLanguages)[0]; } }]); ,其自动化将选择为VenueName,但在(src).Venue.Name类中,该成员称为Venue

您的选择:

  1. VenueName重命名为Venue.VenueName
  2. Venue.Name重命名为DailyEventVM.VenueName
  3. 使用相同的逻辑,地址属性应该被称为DailyEventVM.VenueVenueName,Automapper将在pascal case上分割为DailyEventVM.VenuePlaceAddress

答案 1 :(得分:0)

您可以将多个源对象映射到一个目标对象(就像您的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);