使用 AutoMapper 和 EF Reverse POCO Generator 映射 EF 集合
Mapping EF collection using AutoMapper and EF Reverse POCO Generator
我收到了一个项目,该项目首先使用 EF 数据库、EF Reverse POCO 生成器和 Auto Mapper。我真的很努力地使用所有三个部分来正确建模多对多关系,非常感谢任何帮助。
我的数据库中有以下表格:
+=================+ +==================+ +================+
| Event | | Event_Format | | Format |
+=================+ +==================+ +================+
| Id | | Id | | Id |
| Title | | EventId | | Name |
| Created | | FormatId | | Created |
| CreatedBy | | Created | | CreatedBy |
| | | CreatedBy | | |
+=================+ +==================+ +================+
这会在我的数据层中生成三个 POCO 类:
public class Event {
public int Id { get; set; } // Id (Primary key)
public string Title { get; set; } // Title
public DateTime Created { get; set; } // Created
public string CreatedBy { get; set; } // CreatedBy
public virtual ICollection<EventFormat> EventFormats { get; set; } // Event_Format.FK_Event_Format_Event
}
public class EventFormat
{
public int Id { get; set; } // Id (Primary key)
public int EventId { get; set; } // EventId
public int FormatId { get; set; } // FormatId
public DateTime Created { get; set; } // Created
public string CreatedBy { get; set; } // CreatedBy
public virtual Event Event { get; set; } // FK_Event_Format_Event
public virtual Format Format { get; set; } // FK_Event_Format_Format
}
public class Format
{
public int Id { get; set; } // Id (Primary key)
public string Name { get; set; } // Name
public DateTime Created { get; set; } // Created
public string CreatedBy { get; set; } // CreatedBy
public virtual ICollection<EventFormat> EventFormats { get; set; } // Event_Format.FK_Event_Format_Format
}
在我的 MVC 项目中,我有一个事件和格式的视图模型(但没有 EventFormats,因为它似乎不需要)。
public class Event.ViewModel
{
public int Id { get; set; }
public string Title { get; set; }
public DateTime Created { get; set; }
public string CreatedBy { get; set; }
public List<Format.ViewModel> Formats { get; set; }
}
public class Format.ViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Created { get; set; }
public String CreatedBy { get; set; }
}
以下是 Mapper 配置文件:
protected internal class BookingProfile : Profile
{
public new string ProfileName = "Admin_Booking";
protected override void Configure()
{
CreateMap<Data.Models.Event, Models.Booking.WisconsinFilmFest.ViewModel>()
.ForMember(dst => dst.Created, x => x.MapFrom(src => src.Created.ToLocalTime()))
.ForMember(dst => dst.EventFormats, x => x.MapFrom(src => src.EventFormats.ToList()));
}
}
protected internal class FormatProfile : Profile
{
public new string ProfileName = "Admin_Format";
protected override void Configure()
{
CreateMap<Data.Models.Format, Models.Format.ViewModel>()
.ForMember(dst => dst.Created, x => x.MapFrom(src => src.Created.ToLocalTime()))
.ForMember(dst => dst.Modified, x => x.MapFrom(src => src.Modified.ToLocalTime()));
}
}
当我尝试使用 AutoMapper 将事件映射到 Event.ViewModel 时,它不起作用,因为 EF returns 是 EventFormat 类型(因为有额外的列)。有没有办法告诉 Automapper 获取每个 EventFormat 项的格式,然后将它们映射到 ViewModel 上的格式 属性?
目前我正在做的是使用 Automapper 的 AfterMap() 功能,并循环遍历 EventFormats 中的每个项目以获取格式并将其添加到 ViewModel 的 属性,如下所示:
protected internal class BookingProfile : Profile
{
public new string ProfileName = "Admin_Booking";
protected override void Configure()
{
CreateMap<Data.Models.Event, Models.Booking.WisconsinFilmFest.ViewModel>()
.ForMember(dst => dst.Created, x => x.MapFrom(src => src.Created.ToLocalTime()))
.ForMember(dst => dst.EventFormats, x => x.Ignore())
.AfterMap((src, dst) =>
{
if(src.EventFormats.Any(x => x.Format.Deleted == null))
{
foreach(Data.Models.EventFormat ef in src.EventFormats)
{
dst.EventFormats.Add(Mapper.Map(ef.Format, new Models.Format.ViewModel()));
}
}
});
}
我觉得这有点老套,我希望有更好的方法来做到这一点。
当然可以。指定 AutoMapper 应将 Event.ViewModel.Formats
映射到 EventFormats.Select(ef => ef.Format)
:
Mapper.CreateMap<Format,Format.ViewModel>();
Mapper.CreateMap<Event,Event.ViewModel>()
.ForMember(dest => dest.Formats,
m => m.MapFrom(src => src.EventFormats.Select(ef => ef.Format)));
现在你可以做
var result = db.Events.ProjectTo<Event.ViewModel>();
您应该能够将配置文件中的第一个映射更新为如下所示:
CreateMap<Data.Models.Event, Models.Booking.WisconsinFilmFest.ViewModel>()
.ForMember(dst => dst.Created, x => x.MapFrom(src => src.Created.ToLocalTime()))
.ForMember(dst => dst.Formats, x => x.MapFrom(src => src.EventFormats.Select(y => y.Format).ToList()));
就目前而言,配置文件告诉映射器将源类型的 EventFormats
属性 投影到目标的 EventFormats
属性,当它听起来像你真正想要的是将 EventFormats.Format
属性 投影到 Formats
集合中。
我收到了一个项目,该项目首先使用 EF 数据库、EF Reverse POCO 生成器和 Auto Mapper。我真的很努力地使用所有三个部分来正确建模多对多关系,非常感谢任何帮助。
我的数据库中有以下表格:
+=================+ +==================+ +================+
| Event | | Event_Format | | Format |
+=================+ +==================+ +================+
| Id | | Id | | Id |
| Title | | EventId | | Name |
| Created | | FormatId | | Created |
| CreatedBy | | Created | | CreatedBy |
| | | CreatedBy | | |
+=================+ +==================+ +================+
这会在我的数据层中生成三个 POCO 类:
public class Event {
public int Id { get; set; } // Id (Primary key)
public string Title { get; set; } // Title
public DateTime Created { get; set; } // Created
public string CreatedBy { get; set; } // CreatedBy
public virtual ICollection<EventFormat> EventFormats { get; set; } // Event_Format.FK_Event_Format_Event
}
public class EventFormat
{
public int Id { get; set; } // Id (Primary key)
public int EventId { get; set; } // EventId
public int FormatId { get; set; } // FormatId
public DateTime Created { get; set; } // Created
public string CreatedBy { get; set; } // CreatedBy
public virtual Event Event { get; set; } // FK_Event_Format_Event
public virtual Format Format { get; set; } // FK_Event_Format_Format
}
public class Format
{
public int Id { get; set; } // Id (Primary key)
public string Name { get; set; } // Name
public DateTime Created { get; set; } // Created
public string CreatedBy { get; set; } // CreatedBy
public virtual ICollection<EventFormat> EventFormats { get; set; } // Event_Format.FK_Event_Format_Format
}
在我的 MVC 项目中,我有一个事件和格式的视图模型(但没有 EventFormats,因为它似乎不需要)。
public class Event.ViewModel
{
public int Id { get; set; }
public string Title { get; set; }
public DateTime Created { get; set; }
public string CreatedBy { get; set; }
public List<Format.ViewModel> Formats { get; set; }
}
public class Format.ViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Created { get; set; }
public String CreatedBy { get; set; }
}
以下是 Mapper 配置文件:
protected internal class BookingProfile : Profile
{
public new string ProfileName = "Admin_Booking";
protected override void Configure()
{
CreateMap<Data.Models.Event, Models.Booking.WisconsinFilmFest.ViewModel>()
.ForMember(dst => dst.Created, x => x.MapFrom(src => src.Created.ToLocalTime()))
.ForMember(dst => dst.EventFormats, x => x.MapFrom(src => src.EventFormats.ToList()));
}
}
protected internal class FormatProfile : Profile
{
public new string ProfileName = "Admin_Format";
protected override void Configure()
{
CreateMap<Data.Models.Format, Models.Format.ViewModel>()
.ForMember(dst => dst.Created, x => x.MapFrom(src => src.Created.ToLocalTime()))
.ForMember(dst => dst.Modified, x => x.MapFrom(src => src.Modified.ToLocalTime()));
}
}
当我尝试使用 AutoMapper 将事件映射到 Event.ViewModel 时,它不起作用,因为 EF returns 是 EventFormat 类型(因为有额外的列)。有没有办法告诉 Automapper 获取每个 EventFormat 项的格式,然后将它们映射到 ViewModel 上的格式 属性?
目前我正在做的是使用 Automapper 的 AfterMap() 功能,并循环遍历 EventFormats 中的每个项目以获取格式并将其添加到 ViewModel 的 属性,如下所示:
protected internal class BookingProfile : Profile
{
public new string ProfileName = "Admin_Booking";
protected override void Configure()
{
CreateMap<Data.Models.Event, Models.Booking.WisconsinFilmFest.ViewModel>()
.ForMember(dst => dst.Created, x => x.MapFrom(src => src.Created.ToLocalTime()))
.ForMember(dst => dst.EventFormats, x => x.Ignore())
.AfterMap((src, dst) =>
{
if(src.EventFormats.Any(x => x.Format.Deleted == null))
{
foreach(Data.Models.EventFormat ef in src.EventFormats)
{
dst.EventFormats.Add(Mapper.Map(ef.Format, new Models.Format.ViewModel()));
}
}
});
}
我觉得这有点老套,我希望有更好的方法来做到这一点。
当然可以。指定 AutoMapper 应将 Event.ViewModel.Formats
映射到 EventFormats.Select(ef => ef.Format)
:
Mapper.CreateMap<Format,Format.ViewModel>();
Mapper.CreateMap<Event,Event.ViewModel>()
.ForMember(dest => dest.Formats,
m => m.MapFrom(src => src.EventFormats.Select(ef => ef.Format)));
现在你可以做
var result = db.Events.ProjectTo<Event.ViewModel>();
您应该能够将配置文件中的第一个映射更新为如下所示:
CreateMap<Data.Models.Event, Models.Booking.WisconsinFilmFest.ViewModel>()
.ForMember(dst => dst.Created, x => x.MapFrom(src => src.Created.ToLocalTime()))
.ForMember(dst => dst.Formats, x => x.MapFrom(src => src.EventFormats.Select(y => y.Format).ToList()));
就目前而言,配置文件告诉映射器将源类型的 EventFormats
属性 投影到目标的 EventFormats
属性,当它听起来像你真正想要的是将 EventFormats.Format
属性 投影到 Formats
集合中。