我正在开发一个 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;
}
相关分类