/// <summary> /// Сохраняет все внесенные изменения /// </summary> protected void SaveChanges() { try { //Шаблонный код вызван отсутствием поддержки обновления ключей БД со стороны EntityFramework. //Из-за этого операции вставки, удаления и изменения проводятся через объект заместитель, который позволяет //в случае замены ключа осуществить вставку нового ключа с перепривязкой к нему всех загруженных значений. //Полагаю, что по соображениям производительности справочники лучше менять с помощью SQL #region Шаблонный код обработки заместителей //CertificationDocTypes var delCertificationDocTypes = CertificationDocTypesDB.Except( CertificationDocTypes.Where(d => !d.Added).Select(d => d.InnerReference)).ToList(); foreach (var del in delCertificationDocTypes) { ContextDb.Entry <CertificationDocumentType>(del).State = EntityState.Deleted; } var addCertificationDocTypes = CertificationDocTypes.Where(d => d.Added); foreach (var add in addCertificationDocTypes) { CertificationDocumentType newType = new CertificationDocumentType() { Nom = add.Nom }; ContextDb.CertificationDocumentTypes.Attach(newType); ContextDb.Entry <CertificationDocumentType>(newType).State = EntityState.Added; } var modCertificationDocTypes = CertificationDocTypes.Where(m => m.Modifed); foreach (var mod in modCertificationDocTypes) { CertificationDocumentType oldType = mod.InnerReference; CertificationDocumentType newType = new CertificationDocumentType() { Nom = mod.Nom }; ContextDb.CertificationDocumentTypes.Attach(newType); ContextDb.Entry <CertificationDocumentType>(newType).State = EntityState.Added; foreach (var child in oldType.CertificationDocuments.ToList()) { child.CertificationDocumentTypeNom = newType.Nom; ContextDb.Entry(child).Property(p => p.CertificationDocumentTypeNom).IsModified = true; } ContextDb.Entry <CertificationDocumentType>(oldType).State = EntityState.Deleted; } //SinistreeTypes var delSinistreeTypes = SinistreeTypesDB.Except( SinistreeTypes.Where(d => !d.Added).Select(d => d.InnerReference)).ToList(); foreach (var del in delSinistreeTypes) { ContextDb.Entry <SinistreeType>(del).State = EntityState.Deleted; } var addSinistreeTypes = SinistreeTypes.Where(d => d.Added); foreach (var add in addSinistreeTypes) { SinistreeType newType = new SinistreeType() { Nom = add.Nom }; ContextDb.SinistreeTypes.Attach(newType); ContextDb.Entry <SinistreeType>(newType).State = EntityState.Added; } var modSinistreeTypes = SinistreeTypes.Where(m => m.Modifed); foreach (var mod in modSinistreeTypes) { SinistreeType oldType = mod.InnerReference; SinistreeType newType = new SinistreeType() { Nom = mod.Nom }; ContextDb.SinistreeTypes.Attach(newType); ContextDb.Entry <SinistreeType>(newType).State = EntityState.Added; foreach (var child in oldType.SinistreeRegions.ToList()) { child.SinistreeTypeNom = newType.Nom; ContextDb.Entry(child).Property(p => p.SinistreeTypeNom).IsModified = true; } ContextDb.Entry <SinistreeType>(oldType).State = EntityState.Deleted; } //SujetDocumentTypes var delSujetDocumentTypes = SujetDocumentTypesDB.Except( SujetDocumentTypes.Where(d => !d.Added).Select(d => d.InnerReference)).ToList(); foreach (var del in delSujetDocumentTypes) { ContextDb.Entry <SujetDocumentType>(del).State = EntityState.Deleted; } var addSujetDocumentTypes = SujetDocumentTypes.Where(d => d.Added); foreach (var add in addSujetDocumentTypes) { SujetDocumentType newType = new SujetDocumentType() { Nom = add.Nom }; ContextDb.SujetDocumentTypes.Attach(newType); ContextDb.Entry <SujetDocumentType>(newType).State = EntityState.Added; } var modSujetDocumentTypes = SujetDocumentTypes.Where(m => m.Modifed); foreach (var mod in modSujetDocumentTypes) { SujetDocumentType oldType = mod.InnerReference; SujetDocumentType newType = new SujetDocumentType() { Nom = mod.Nom }; ContextDb.SujetDocumentTypes.Attach(newType); ContextDb.Entry <SujetDocumentType>(newType).State = EntityState.Added; foreach (var child in oldType.SujetDocuments.ToList()) { child.SujetDocumentTypeNom = newType.Nom; ContextDb.Entry(child).Property(p => p.SujetDocumentTypeNom).IsModified = true; } ContextDb.Entry <SujetDocumentType>(oldType).State = EntityState.Deleted; } //UtilisationTypes var delUtilisationTypes = UtilisationTypesDB.Except( UtilisationTypes.Where(d => !d.Added).Select(d => d.InnerReference)).ToList(); foreach (var del in delUtilisationTypes) { ContextDb.Entry <UtilisationType>(del).State = EntityState.Deleted; } var addUtilisationTypes = UtilisationTypes.Where(d => d.Added); foreach (var add in addUtilisationTypes) { UtilisationType newType = new UtilisationType() { Nom = add.Nom }; ContextDb.UtilisationTypes.Attach(newType); ContextDb.Entry <UtilisationType>(newType).State = EntityState.Added; } var modUtilisationTypes = UtilisationTypes.Where(m => m.Modifed); foreach (var mod in modUtilisationTypes) { UtilisationType oldType = mod.InnerReference; UtilisationType newType = new UtilisationType() { Nom = mod.Nom }; ContextDb.UtilisationTypes.Attach(newType); ContextDb.Entry <UtilisationType>(newType).State = EntityState.Added; foreach (var child in oldType.Utilisations.ToList()) { child.UtilisationTypeNom = newType.Nom; ContextDb.Entry(child).Property(p => p.UtilisationTypeNom).IsModified = true; } ContextDb.Entry <UtilisationType>(oldType).State = EntityState.Deleted; } //Etats var delEtats = EtatsDB.Except( Etats.Where(d => !d.Added).Select(d => d.InnerReference)).ToList(); foreach (var del in delEtats) { ContextDb.Entry <Etat>(del).State = EntityState.Deleted; } var addEtats = Etats.Where(d => d.Added); foreach (var add in addEtats) { Etat newType = new Etat() { Nom = add.Nom }; ContextDb.Etats.Attach(newType); ContextDb.Entry <Etat>(newType).State = EntityState.Added; } var modEtats = Etats.Where(m => m.Modifed); foreach (var mod in modEtats) { Etat oldType = mod.InnerReference; Etat newType = new Etat() { Nom = mod.Nom }; ContextDb.Etats.Attach(newType); ContextDb.Entry <Etat>(newType).State = EntityState.Added; foreach (var child in oldType.Sujets.ToList()) { child.Nationalite = newType.Nom; ContextDb.Entry(child).Property(p => p.Nationalite).IsModified = true; } ContextDb.Entry <Etat>(oldType).State = EntityState.Deleted; } //JuridiqueTypes var delJuridiqueTypes = JuridiqueTypesDB.Except( JuridiqueTypes.Where(d => !d.Added).Select(d => d.InnerReference)).ToList(); foreach (var del in delJuridiqueTypes) { foreach (var tran in del.TransactionTypes.ToList()) { ContextDb.Entry <TransactionType>(tran).State = EntityState.Deleted; } ContextDb.Entry <JuridiqueType>(del).State = EntityState.Deleted; } var addJuridiqueTypes = JuridiqueTypes.Where(d => d.Added); foreach (var add in addJuridiqueTypes) { JuridiqueType newType = new JuridiqueType() { Nom = add.Nom }; ContextDb.JuridiqueTypes.Attach(newType); ContextDb.Entry <JuridiqueType>(newType).State = EntityState.Added; } var modJuridiqueTypes = JuridiqueTypes.Where(m => m.Modifed); foreach (var mod in modJuridiqueTypes) { JuridiqueType oldType = mod.InnerReference; JuridiqueType newType = new JuridiqueType() { Nom = mod.Nom }; ContextDb.JuridiqueTypes.Attach(newType); ContextDb.Entry <JuridiqueType>(newType).State = EntityState.Added; foreach (var child in oldType.TransactionTypes.ToList()) { child.JuridiqueTypeNom = newType.Nom; ContextDb.Entry(child).Property(p => p.JuridiqueTypeNom).IsModified = true; } ContextDb.Entry <JuridiqueType>(oldType).State = EntityState.Deleted; } ObservableCollection <TransactionType> TransactionTypesDB = new ObservableCollection <TransactionType>(JuridiqueTypesDB.SelectMany(j => j.TransactionTypes).ToList()); foreach (var jur in JuridiqueTypes) { foreach (var tr in jur.TransactionTypes) { if (tr.JuridiqueType == null) { tr.JuridiqueType = jur; } } } ObservableCollection <TransactionTypeProxy> TransactionTypes = new ObservableCollection <TransactionTypeProxy>(JuridiqueTypes.SelectMany(j => j.TransactionTypes).ToList()); //TransactionTypes var delTransactionTypes = TransactionTypesDB.Except( TransactionTypes.Where(d => !d.Added).Select(d => d.InnerReference)).ToList(); foreach (var del in delTransactionTypes) { ContextDb.Entry <TransactionType>(del).State = EntityState.Deleted; } var addTransactionTypes = TransactionTypes.Where(d => d.Added); foreach (var add in addTransactionTypes) { TransactionType newType = new TransactionType() { Nom = add.Nom, JuridiqueTypeNom = add.JuridiqueType.Nom }; ContextDb.TransactionTypes.Attach(newType); ContextDb.Entry <TransactionType>(newType).State = EntityState.Added; } var modTransactionTypes = TransactionTypes.Where(m => m.Modifed); foreach (var mod in modTransactionTypes) { TransactionType oldType = mod.InnerReference; TransactionType newType = new TransactionType() { Nom = mod.Nom, JuridiqueTypeNom = mod.JuridiqueType.Nom }; ContextDb.TransactionTypes.Attach(newType); ContextDb.Entry <TransactionType>(newType).State = EntityState.Added; foreach (var child in oldType.Transactions.ToList()) { child.TransactionTypeNom = newType.Nom; ContextDb.Entry(child).Property(p => p.TransactionTypeNom).IsModified = true; } ContextDb.Entry <TransactionType>(oldType).State = EntityState.Deleted; } #endregion if (ContextDb.ChangeTracker.HasChanges()) //Если были зафиксированы изменения { ContextDb.SaveChanges(); CreateProxy(); //Воссоздаем заместителей //Уведомляем об изменении справочников Messenger.Default.Send <ReferenceRefreshedMessage>(new ReferenceRefreshedMessage()); } } catch (Exception e) { string message = "Редактирование нарушает целостность данных:\n" + e.Message; Exception ie = e.InnerException; while (ie != null) { message += '\n' + ie.Message; ie = ie.InnerException; } message += "\nДля сохранения целостности данных результаты редактирования аннулированы"; MessageBox.Show(message, "Ошибка ввода данных", MessageBoxButton.OK); //Отменяем внесенные изменения ContextDb.DiscardAllChanges(); LoadDataAsync(); //Полная перезагрузка данных } }
public UtilisationTypeProxy(UtilisationType innerReference) { InnerReference = innerReference; Nom = innerReference.Nom; }