用于将匿名类型投影到视图模型的自动映射查询

时间:2015-02-19 16:30:28

标签: c# linq entity-framework automapper

我有一个非常基本的控制器,它执行Linq to Entities查询,我希望能够使用AutoMapper将结果投影到viewmodel上 - 但是我收到了错误:

cannot convert from 'System.Collections.Generic.List<AnonymousType#1>' to 'System.Collections.Generic.IList<tb.Models.Tour>'

控制器:

var tours2 = (from t in db.Tours
                     join d in db.TourDates on t.TourId equals d.TourId
                     join c in db.TourCategories on t.TourCategoryId equals c.TourCategoryId
                     where d.Date == dte && t.TourCategoryId == id
                     select new
                    {
                        Id = t.TourId,
                        TourName = t.TourName,
                        TourCategoryId = t.TourCategoryId,
                        Bookings = db.Bookings.Where(b => d.TourDateId == b.TourDateId).Count()                            
                    }).ToList();

        Mapper.CreateMap<IList<Tour>, IList<ToursAvail2VM>>();
        IList<ToursAvail2VM> toursvm = Mapper.Map<IList<Tour>, IList<ToursAvail2VM>>(tours2);

视图模型:

 public class ToursAvail2VM
 {
    public int Id { get; set; }
    public int TourCategoryId { get; set; }
    public string TourName { get; set; }
    public int Bookings { get; set; }
 }

如何获取投射到我的toursvm课程的结果列表?

感谢任何建议,马克

2 个答案:

答案 0 :(得分:4)

对于此示例,我使用的是AutoMapper LINQ projection capabilities

// This would be somewhere in initialization
Mapper.CreateMap<Tour, ToursAvail2VM>()
    .ForMember(d => d.Bookings, opt => opt.MapFrom(src => 
        src.TourDates.Sum(td => td.Bookings.Count()));

var toursvm = (from t in db.Tours
                 join d in db.TourDates on t.TourId equals d.TourId
                 join c in db.TourCategories on t.TourCategoryId equals c.TourCategoryId
                 where d.Date == dte && t.TourCategoryId == id
                )
              .Project().To<ToursAvail2VM>()
              .ToList();

我假设您在模型中包含导航属性,以便您可以直接从Tour导览到TourDates导航到预订。

答案 1 :(得分:1)

您的linq查询返回的是匿名类型,而不是Tour。您需要明确指定要返回的类,否则AutoMapper无法处理它。

但是,由于您使用的是Linq to Entities,因此无法直接指定ToursAvail2VM。您可以执行以下操作:选择匿名类型,然后立即选择ToursAvail2VM,如下所示:

IList<ToursAvail2VM> toursvm =
                (from vm in
                    (from t in db.Tours
                     join d in db.TourDates on t.TourId equals d.TourId
                     join c in db.TourCategories on t.TourCategoryId equals c.TourCategoryId
                     where d.Date == dte && t.TourCategoryId == id
                     select new
                    {
                        Id = t.TourId,
                        TourName = t.TourName,
                        TourCategoryId = t.TourCategoryId,
                        Bookings = db.Bookings.Where(b => d.TourDateId == b.TourDateId).Count()                            
                    }).ToList()
                select new ToursAvail2VM
                    {
                         Id = vm.Id,
                         TourName = vm.TourName,
                         TourCategoryId = vm.TourCategoryId,
                         Bookings = vm.Bookings
                    }).ToList();