gpt4 book ai didi

c# - AutoMapper 在 map 中引用 map

转载 作者:行者123 更新时间:2023-11-30 12:26:31 25 4
gpt4 key购买 nike

我真的在为如何实现这一目标而苦苦挣扎,我基本上是在尝试为我的 Index 查看 ClubViewModel 列表,但要做到这一点,我需要匹配我的俱乐部列表。我正在使用 AutoMapper,除了 CalendarEntry 之外的所有东西都运行良好,它是我的数据库模型中的列表和我的 View 模型中的展平类。

我真的不想改变我的 View 模型,因为我以我想要的方式创建 View (每天的 bool 值和相关的开始/结束时间)。

首先是 Controller ,它成功地映射了大部分类:

    public ActionResult Index()
{
var clubsList = _service.GetAllClubs();
IList<ClubViewModel> clubsViewModelList = new List<ClubViewModel>();

foreach (var item in clubsList)
{
clubsViewModelList.Add(AutoMapper.Mapper.Map<ClubViewModel>(item));
}
return View(clubsViewModelList);
}

这是我的存储库模型枚举以及我的Web ViewModels

   public class Club
{
public int ClubId { get; set; }
public string Organisation { get; set; }
public List<CalendarEntry> MeetingDays { get; set; }
}

public class CalendarEntry
{
public int CalendarEntryId { get; set; }
public int ClubId { get; set; }
public Days Day { get; set; }
public DateTime From { get; set; }
public DateTime To { get; set; }
}

public enum Days
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}

public class ClubViewModel
{
public int ClubId { get; set; }
public string Organisation { get; set; }
public CalendarEntryViewModel CalendarEntryViewModel { get; set; }
}

public class CalendarEntryViewModel
{
public bool IsMonday { get; set; }
public bool IsTuesday { get; set; }
public bool IsWednesday { get; set; }
public bool IsThursday { get; set; }
public bool IsFriday { get; set; }
public DateTime? MondayFrom { get; set; }
public DateTime? MondayTo { get; set; }
public DateTime? TuesdayFrom { get; set; }
public DateTime? TuesdayTo { get; set; }
public DateTime? WednesdayFrom { get; set; }
public DateTime? WednesdayTo { get; set; }
public DateTime? ThursdayFrom { get; set; }
public DateTime? ThursdayTo { get; set; }
public DateTime? FridayFrom { get; set; }
public DateTime? FridayTo { get; set; }
}

最后是我的AutoMapper配置方法:

public static void RegisterMappings()
{
Mapper.CreateMap<Club, ClubViewModel>()

.ForMember(dest => dest.CalendarEntryViewModel,
opts => opts.Ignore());

Mapper.CreateMap<CalendarEntry, CalendarEntryViewModel>()

.ForMember(dest => dest.IsMonday, opts => opts.Equals(true))
.ForMember(dest => dest.IsTuesday, opts => opts.Equals(true))
.ForMember(dest => dest.IsWednesday, opts => opts.Equals(true))
.ForMember(dest => dest.IsThursday, opts => opts.Equals(true))
.ForMember(dest => dest.IsFriday, opts => opts.Equals(true))

.ForMember(dest => dest.MondayFrom, opts => opts.Equals(DateTime.Now))
.ForMember(dest => dest.MondayTo, opts => opts.Equals(DateTime.Now))
.ForMember(dest => dest.TuesdayFrom, opts => opts.Equals(DateTime.Now))
.ForMember(dest => dest.TuesdayTo, opts => opts.Equals(DateTime.Now))
.ForMember(dest => dest.WednesdayFrom, opts => opts.Equals(DateTime.Now))
.ForMember(dest => dest.WednesdayTo, opts => opts.Equals(DateTime.Now))
.ForMember(dest => dest.ThursdayFrom, opts => opts.Equals(DateTime.Now))
.ForMember(dest => dest.ThursdayTo, opts => opts.Equals(DateTime.Now))
.ForMember(dest => dest.FridayFrom, opts => opts.Equals(DateTime.Now))
.ForMember(dest => dest.FridayTo, opts => opts.Equals(DateTime.Now));

Mapper.AssertConfigurationIsValid();
}

目前,我只是硬编码了 bools/dates 的值,同时尝试让事情正常进行。

无论如何我可以将第二个 CalendarEntry 添加到 CalendarEntryViewModel Map 到 ClubClubViewModel Map作为额外成员还是我这样做完全错误?

最佳答案

您应该解压缩 CalendarEntryViewModel,以便它更接近地代表您域中的日历条目。您目前正在尝试将列表插入扁平化对象中……这会让您以后遭受更多痛苦。

在开始之前,我必须提一下:

foreach (var item in clubsList)
{
clubsViewModelList.Add(AutoMapper.Mapper.Map<ClubViewModel>(item));
}

Automapper 可以处理列表……这样就可以:

var clubsViewModelList = Mapper.Map<IList<Club>, IList<ClubViewModel>>(clubsList);

解压 View 模型

我知道这就是您所说的您不想做的......但您确实应该这样做。它将使您的域和 View 之间的映射更加简单。出于很多原因,我完全赞成将它们分开,但我认为您尝试将这种域模型扁平化为单个 View 模型并没有给自己带来任何好处。所以将它解压到多个 View 模型:

public class ClubViewModel
{
public int ClubId { get; set; }
public string Organisation { get; set; }
public IList<CalendarEntryViewModel> CalendarEntries { get; set; } // <--- a list of them
}

然后你的 map 变成:

.ForMember(dest => dest.IsMonday, opt => opt.MapFrom(src => src.Day == Days.Monday))
.ForMember(dest => dest.IsTuesday, opt => opt.MapFrom(src => src.Day == Days.Tuesday))
/* etc... */

然后,删除所有可为空的日期并只用两个字段表示此条目:

public DateTime? From { get; set; }        
public DateTime? To { get; set; }

然后您可以按天订购:

foreach (var club in clubsViewModelList) {
club.CalendarEntries = club.CalendarEntries.OrderBy(x => x.Day).ToList();
}

然后在您的 View 中..按顺序渲染它们:

@foreach (var calendarEntry in club.CalendarEntries) {
Day: @calendarEntry.Day.ToString()
From: @calendarEntry.From.ToString("D")
}

..等等

当需要创建时...您只需根据需要呈现您的条目:

public class ClubCalendarEntryCreateViewModel {
/* other properties here */
public IList<CalendarEntryViewModel> Days { get; set; }
}

然后在你的 Controller 中:

viewModel.CalendarEntries = new ClubCalendarEntryCreateViewModel {
Days = new List<CalendarEntryViewModel>() {
new CalendarEntryViewModel {
IsMonday = true
},
new CalendarEntryViewModel {
IsTuesday = true
},
/* etc... */
}
};

然后您只需渲染它们并在您的 POST 方法中接受它。您对该方法的映射变为:

club.CalendarEntries = Mapper.Map<IList<CalendarEntryViewModel>, IList<CalendarEntry>>(viewModel.CalendarEntries.Days);

我在这里遗漏了一点(比如你将如何改造你的 CalendarEntry 域对象).. 希望你能填空并理解我的意思。我知道这看起来工作量很大——但你以后会做得更好。您的映射不会像现在这样成为您的敌人(它们永远不应该成为您的敌人),并且您的代码将变得更加清晰。

我希望这对您有所帮助......这可能不是您想听到的,但绝对是我会如何去做(或类似的,如果有更多要求)。

关于c# - AutoMapper 在 map 中引用 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28364254/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com