// Copyright (C) Stichting Deltares 2016. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.Collections.Generic; using System.Data.Entity; using System.Diagnostics; using System.Linq; using Application.Ringtoets.Storage.Converters; using Application.Ringtoets.Storage.DbContext; using Application.Ringtoets.Storage.Exceptions; using Application.Ringtoets.Storage.Properties; using Core.Common.Base.Data; using Ringtoets.Integration.Data; namespace Application.Ringtoets.Storage.Persistors { /// /// Persistor for . /// public class ProjectPersistor { private readonly DbSet projectEntitySet; private readonly ProjectConverter converter; private readonly Dictionary insertedList = new Dictionary(); private readonly ICollection modifiedList = new List(); private readonly AssessmentSectionPersistor assessmentSectionEntityPersistor; /// /// Instantiate a new . /// /// The storage context. /// Thrown when is null. public ProjectPersistor(IRingtoetsEntities ringtoetsContext) { if (ringtoetsContext == null) { throw new ArgumentNullException("ringtoetsContext"); } projectEntitySet = ringtoetsContext.ProjectEntities; converter = new ProjectConverter(); assessmentSectionEntityPersistor = new AssessmentSectionPersistor(ringtoetsContext); } /// /// Gets the only as from the sequence. /// /// A new , loaded from the sequence, or null when not found. /// Thrown when there are more than one elements in the sequence. public Project GetEntityAsModel() { var entry = projectEntitySet.SingleOrDefault(); if (entry == null) { return null; } var project = converter.ConvertEntityToModel(entry); var nrOfItems = entry.AssessmentSectionEntities.Count; var assessmentSections = new object[nrOfItems]; foreach (var sectionEntity in entry.AssessmentSectionEntities) { assessmentSections[sectionEntity.Order] = assessmentSectionEntityPersistor.LoadModel(sectionEntity); } // Add to items sorted foreach (var assessmentSection in assessmentSections) { project.Items.Add(assessmentSection); } return project; } /// /// Insert the , based upon the , in the sequence. /// /// Execute afterwards to update the storage. /// to be inserted in the sequence. /// New instance of . /// Thrown when is null. /// The parentNavigationProperty is read-only. public void InsertModel(Project project) { if (project == null) { throw new ArgumentNullException("project", @"Cannot update databaseSet when no project is set."); } var entity = new ProjectEntity(); projectEntitySet.Add(entity); insertedList.Add(entity, project); converter.ConvertModelToEntity(project, entity); if (project.StorageId > 0) { modifiedList.Add(entity); } InsertChildren(project, entity); } /// /// Updates the , based upon the , in the sequence. /// /// Execute afterwards to update the storage. /// The to be saved in the storage. /// The . /// Thrown when is null. /// Thrown when: /// is not found. /// More than one satisfies the condition in predicate. /// /// The parentNavigationProperty is read-only. public void UpdateModel(Project model) { if (model == null) { throw new ArgumentNullException("model", @"Cannot update databaseSet when no project is set."); } ProjectEntity entity; try { entity = projectEntitySet.SingleOrDefault(db => db.ProjectEntityId == model.StorageId); } catch (InvalidOperationException exception) { throw new EntityNotFoundException(String.Format(Resources.Error_Entity_Not_Found_0_1, "ProjectEntity", model.StorageId), exception); } if (entity == null) { throw new EntityNotFoundException(String.Format(Resources.Error_Entity_Not_Found_0_1, "ProjectEntity", model.StorageId)); } modifiedList.Add(entity); converter.ConvertModelToEntity(model, entity); UpdateChildren(model, entity); } /// /// Removes all entities from that are not marked as 'updated'. /// public void RemoveUnModifiedEntries() { var untouchedList = projectEntitySet.ToList().Where(e => !modifiedList.Contains(e)); projectEntitySet.RemoveRange(untouchedList); modifiedList.Clear(); } /// /// Perform actions that can only be executed after has been called. /// public void PerformPostSaveActions() { UpdateStorageIdsInModel(); assessmentSectionEntityPersistor.PerformPostSaveActions(); } /// /// Updates the children of , in reference to , in the storage. /// /// The of which children need to be updated. /// Referenced . private void UpdateChildren(Project project, ProjectEntity entity) { var order = 0; foreach (var item in project.Items.Where(i => i is AssessmentSection).Cast()) { assessmentSectionEntityPersistor.UpdateModel(entity.AssessmentSectionEntities, item, order); order++; } assessmentSectionEntityPersistor.RemoveUnModifiedEntries(entity.AssessmentSectionEntities); } /// /// Inserts the children of , in reference to , in the storage. /// /// The of which children need to be inserted. /// Referenced . private void InsertChildren(Project project, ProjectEntity entity) { var order = 0; foreach (var item in project.Items.Where(i => i is AssessmentSection).Cast()) { assessmentSectionEntityPersistor.InsertModel(entity.AssessmentSectionEntities, item, order); order++; } assessmentSectionEntityPersistor.RemoveUnModifiedEntries(entity.AssessmentSectionEntities); } /// /// Updates the StorageId of each inserted to the /// of the corresponding . /// /// must have been called to update the ids. private void UpdateStorageIdsInModel() { foreach (var entry in insertedList) { Debug.Assert(entry.Key.ProjectEntityId > 0, "ProjectEntityId is not set. Have you called IRingtoetsEntities.SaveChanges?"); entry.Value.StorageId = entry.Key.ProjectEntityId; } insertedList.Clear(); } } }