使用 Automapper 简洁地插入/更新/删除可枚举的子实体

我正在开发一个 ASP.Net MVC 应用程序,我有一个“报告”对象,它具有相关的可枚举项,例如日程表和注释。使用 AutoMapper,可以轻松地从报表实体转换为视图模型并返回,但是当我尝试将报表对象(从视图模型映射到现有实体)保存回数据库时遇到问题。


更具体地说,我似乎无法使用 automapper 简洁地更新现有实体、插入新实体和删除旧实体。例如,每当我将计划从视图模型映射到报告实体时,它都会删除现有计划,然后创建新计划(具有递增索引)。这是我的代码:


public class ScheduleViewModel

{

    public int ScheduleID { get; set; }

    public int ReportID { get; set; }

    public int Month { get; set; }

    public int Day { get; set; }

    public string Description { get; set; }

}


public class ReportViewModel

{

    public int ReportID { get; set; }

    public List<ScheduleViewModel> Schedules { get; set; }


    public void Save()

    {

        dbContext db = new dbContext();

        Report original = db.Reports.SingleOrDefault(o => o.ReportID == ReportID);


        var config = new MapperConfiguration(cfg =>

        {

            cfg.CreateMap<ReportViewModel, Report>();

        });


        config.AssertConfigurationIsValid();

        var mapper = config.CreateMapper();

        mapper.Map(this, original);

        db.SaveChanges();

    }

}

我的 Report 对象有一个关系键(和一个“Schedules”导航属性),所以一切都从我的视图模型成功映射到“原始”报告。新计划的 ScheduleID 为 0,因为它们尚未分配,并且它们使用自动增量添加到数据库中,这正是我想要的。现有计划在映射到“原始”报告对象时保持其 ScheduleID,但一旦调用 SaveChanges,就会收到递增的 ID。


据我了解,无论视图模型 ID 属性是否与数据库中的主键匹配(在这种情况下,它是 ReportID 和 ScheduleID 的组合),我都会将新的计划附加到上下文中。有没有一种干净的方法,使用某种 ForMember(report => report.Schedules),如果视图模型对象可以映射到现有键,则使实体框架理解不会破坏我现有实体的表达式?


我正在寻找功能类似于下面代码的东西,但由于我将有许多可枚举属性附加到我的报表对象,我不想为每个属性维护这些部分:


foreach (Schedule schedule in db.Schedules.Where(s => s.ReportID == this.ReportID))

{

    ScheduleViewModel svm = this.Schedules.FirstOrDefault(s => s.ScheduleID == schedule.ScheduleID);


    //Update Existing

    if (svm != null)

        db.Entry(schedule).CurrentValues.SetValues(svm);


    //Delete Missing

    else

        db.Entry(schedule).State = System.Data.Entity.EntityState.Deleted;

}



繁星coding
浏览 171回答 1
1回答
打开App,查看更多内容
随时随地看视频慕课网APP