Я работаю над приложением 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();
}
}
Мой объект отчета имеет реляционный ключ (и навигационное свойство «Расписания»), поэтому все успешно отображается из моей модели представления в «исходный» отчет.Новые расписания имеют ScheduleID 0, поскольку они не были назначены, и они добавляются в базу данных с помощью автоинкремента, чего я и хочу.Существующие расписания сохраняют свой ScheduleID при сопоставлении с «исходным» объектом отчета, но затем получают увеличенные идентификаторы после вызова SaveChanges.
Насколько я понимаю, я присоединяю новые расписания к контексту независимо от того,Свойства идентификатора модели представления соответствуют первичному ключу в базе данных (в данном случае это составная часть ReportID и ScheduleID).Есть ли чистый способ, использующий какое-то ForMember (report => report.Schedules) выражение, которое заставляет Entity Framework понимать, что не следует уничтожать мои существующие сущности, если объект View Model может отображаться в существующий ключ?
Я ищу что-то похожее на приведенный ниже код, но, поскольку у меня будет много перечисляемых свойств, связанных с моими объектами отчета, я не хочу поддерживать эти разделы для каждого:
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;
}
//Insert New
foreach(ScheduleViewModel svm in this.Schedules.Where(s => s.ScheduleID == 0))
{
svm.ReportID = ReportID;
Schedule schedule = new Schedule() {};
db.Schedules.Add(schedule);
db.Entry(schedule).CurrentValues.SetValues(svm);
}