//////////////////////////////////////////////////////////// public static CResultAErreur CanDelete(CListeObjetsDonnees liste) { CResultAErreur result = CResultAErreur.True; if (liste.Count == 0) { return(result); } bool bPasObjetAIdNumeriqueAuto = false; foreach (CObjetDonnee objet in liste) { if (!(objet is CObjetDonneeAIdNumerique)) { bPasObjetAIdNumeriqueAuto = true; result = objet.CanDelete(); } else { result = ((CObjetDonneeAIdNumerique)objet).MyCanDelete(); } if (!result) { return(result); } } if (bPasObjetAIdNumeriqueAuto) { return(result); } Type typeElements = liste.TypeObjets; string strListeIds = ""; int nCount = liste.Count; int nTailleParBloc = 500; string strNomTable = CContexteDonnee.GetNomTableForType(liste.TypeObjets); //Copie de la liste, pour sécuriser le parcours List <CObjetDonneeAIdNumerique> lstElements = liste.ToList <CObjetDonneeAIdNumerique>(); //Travaille par bloc de 500 enregistrements pour les contrôles for (int nBloc = 0; nBloc < nCount; nBloc += nTailleParBloc) { StringBuilder bl = new StringBuilder(); int nMin = Math.Min(nBloc + nTailleParBloc, nCount); //Liste des éléments du bloc en cours for (int nElement = nBloc; nElement < nMin; nElement++) { bl.Append(lstElements[nElement].Id); bl.Append(','); } if (bl.Length > 0) { bl.Remove(bl.Length - 1, 1); //Liste des objets du bloc en cours CListeObjetsDonnees listePartielle = new CListeObjetsDonnees(liste.ContexteDonnee, liste.TypeObjets, false); listePartielle.Filtre = new CFiltreData( liste.ContexteDonnee.GetTableSafe(strNomTable).PrimaryKey[0].ColumnName + " in (" + bl.ToString() + ")");; listePartielle.InterditLectureInDB = true; //Pas besoin de lire car les éléments sont déjà dans le contexte de données listePartielle.Filtre.IntegrerLesElementsSupprimes = liste.Filtre != null? liste.Filtre.IntegrerLesElementsSupprimes: (liste.FiltrePrincipal != null?liste.FiltrePrincipal.IntegrerLesElementsSupprimes:false); listePartielle.Filtre.IgnorerVersionDeContexte = liste.Filtre != null ? liste.Filtre.IgnorerVersionDeContexte: (liste.FiltrePrincipal != null ? liste.FiltrePrincipal.IgnorerVersionDeContexte : false); strListeIds = bl.ToString(); foreach (CInfoRelation relation in CContexteDonnee.GetListeRelationsTable(strNomTable)) { if (relation.TableParente == strNomTable) //Relation fille { if (!relation.Composition) //Ce n'est pas une composition, il ne faut pas qu'il y ait de fils { if (!relation.PasserLesFilsANullLorsDeLaSuppression) //Sinon, ce n'est pas grave ! { IObjetServeur objServeur = liste.ContexteDonnee.GetTableLoader(relation.TableFille); //Ceux pour lesquels les dépendances sont chargés n'ont pas besoin de regarder la base StringBuilder strIdsAVoirDansLaBase = new StringBuilder(); DataRelation dataRel = null; foreach (DataRelation childRel in liste.ContexteDonnee.GetTableSafe(relation.TableParente).ChildRelations) { bool bCestElle = false; if (childRel.ChildTable.TableName == relation.TableFille) { if (childRel.ChildColumns.Length == relation.ChampsFille.Length) { bCestElle = true; for (int nCol = 0; nCol < childRel.ChildColumns.Length; nCol++) { if (childRel.ChildColumns[nCol].ColumnName != relation.ChampsFille[nCol]) { bCestElle = false; break; } } } } if (bCestElle) { dataRel = childRel; break; } } if (dataRel != null) { foreach (CObjetDonneeAIdNumerique objetTmp in listePartielle) { string strFKName = objetTmp.ContexteDonnee.GetForeignKeyName(dataRel); if (objetTmp.IsDependanceChargee(strFKName)) { DataRow[] rowsFilles = objetTmp.Row.Row.GetChildRows(dataRel); if (rowsFilles.Length > 0) { result.EmpileErreur(I.T("Cannot delete element @1, @2 elements (@3) are linked|190", objetTmp.DescriptionElement, rowsFilles.Length.ToString(), relation.TableFille)); return(result); } } else { strIdsAVoirDansLaBase.Append(objetTmp.Id); strIdsAVoirDansLaBase.Append(','); } } if (strIdsAVoirDansLaBase.Length > 0) { strIdsAVoirDansLaBase.Remove(strIdsAVoirDansLaBase.Length - 1, 1); } } else { strIdsAVoirDansLaBase.Append(strListeIds); } if (strIdsAVoirDansLaBase.Length > 0) { CFiltreData filtre = new CFiltreData(relation.ChampsFille[0] + " in (" + strIdsAVoirDansLaBase.ToString() + ")"); int nNb = objServeur.CountRecords(relation.TableFille, filtre); if (nNb != 0) { Type tp = CContexteDonnee.GetTypeForTable(relation.TableFille); result.EmpileErreur(I.T("Cannot delete '@1' elements because '@2' elements are dependent|160", DynamicClassAttribute.GetNomConvivial(typeElements), DynamicClassAttribute.GetNomConvivial(tp))); return(result); } } } } else //C'est une composition { CListeObjetsDonnees listeDep = listePartielle.GetDependancesFilles(relation, liste.Filtre != null && liste.Filtre.IntegrerLesElementsSupprimes || liste.FiltrePrincipal != null && liste.FiltrePrincipal.IntegrerLesElementsSupprimes); result = CanDelete(listeDep); if (!result) { return(result); } } } } //Peut-on supprimer les relationsTypeId foreach (RelationTypeIdAttribute relation in CContexteDonnee.RelationsTypeIds) { Type tpLiens = CContexteDonnee.GetTypeForTable(relation.TableFille); if (relation.AppliquerContrainteIntegrite && !relation.CanDeleteToujours && relation.IsAppliqueToType(typeElements)) { CListeObjetsDonnees listeTypeId = new CListeObjetsDonnees(liste.ContexteDonnee, tpLiens, false); CFiltreData filtre = new CFiltreData( relation.ChampType + "=@1 and " + relation.ChampId + " in (" + strListeIds + ")", typeElements.ToString()); listeTypeId.Filtre = filtre; if (relation.Composition) { result = CanDelete(listeTypeId); if (!result) { return(result); } } else { int nNb = listeTypeId.CountNoLoad; if (nNb != 0) { Type tp = CContexteDonnee.GetTypeForTable(relation.TableFille); result.EmpileErreur(I.T("Cannot delete the required elements because elements @1 exist in database|161", DynamicClassAttribute.GetNomConvivial(tpLiens))); return(result); } } } } if (IsUtiliseDansVersionFuture(liste, strListeIds)) { result.EmpileErreur(I.T("Cannot delete these elements because they will be used in future versions|187")); return(result); } } } return(result); }
//////////////////////////////////////////////////////////// public static CResultAErreur DeleteAvecCascadeSansControleDoncIlFautEtreSurDeSoi(CListeObjetsDonnees liste, bool bDansContexteCourant) { CResultAErreur result = CResultAErreur.True; bool bOldEnforce = liste.ContexteDonnee.EnforceConstraints; StringBuilder bl = new StringBuilder(); foreach (CObjetDonneeAIdNumerique objetTmp in liste) { if (objetTmp.IsValide()) { bl.Append(objetTmp.Id); bl.Append(','); } } if (bl.Length == 0) { return(result); } bl.Remove(bl.Length - 1, 1); if (IsUtiliseDansVersionFuture(liste, bl.ToString())) { result.EmpileErreur(I.T("Cannot delete these elements because they will be used in future versions|187")); return(result); } try { liste.ContexteDonnee.EnforceConstraints = false; if (liste.Count == 0) { return(result); } foreach (CObjetDonneeAIdNumerique objet in liste) { if (objet.IsValide()) { result = objet.MyCanDelete(); if (!result) { return(result); } } } Type typeElements = liste.TypeObjets; string strListeIds = ""; foreach (CObjetDonneeAIdNumerique objet in liste) { if (objet.IsValide()) { strListeIds += objet.Id.ToString() + ","; } } strListeIds = strListeIds.Substring(0, strListeIds.Length - 1); string strNomTable = CContexteDonnee.GetNomTableForType(liste.TypeObjets); foreach (CInfoRelation relation in CContexteDonnee.GetListeRelationsTable(strNomTable)) { if (relation.TableParente == strNomTable) { //Car la dépendance doit être lue pour la suppression CListeObjetsDonnees listeDep = liste.GetDependancesFilles(relation); result = DeleteAvecCascadeSansControleDoncIlFautEtreSurDeSoi(listeDep, bDansContexteCourant); if (!result) { return(result); } } } if (typeElements.GetCustomAttributes(typeof(NoRelationTypeIdAttribute), true).Length == 0) { //Peut-on supprimer les relationsTypeId foreach (RelationTypeIdAttribute relation in CContexteDonnee.RelationsTypeIds) { Type tpLiens = CContexteDonnee.GetTypeForTable(relation.TableFille); CListeObjetsDonnees listeTypeId = new CListeObjetsDonnees(liste.ContexteDonnee, tpLiens, false); CFiltreData filtre = new CFiltreData( relation.ChampType + "=@1 and " + relation.ChampId + " in (" + strListeIds + ")", typeElements.ToString()); listeTypeId.Filtre = filtre; listeTypeId.PreserveChanges = true; result = DeleteAvecCascadeSansControleDoncIlFautEtreSurDeSoi(listeTypeId, bDansContexteCourant); } } foreach (CObjetDonneeAIdNumerique objet in liste.ToArrayList()) { if (objet.IsValide()) { result = objet.DoDeleteInterneACObjetDonneeNePasUtiliserSansBonneRaison(bDansContexteCourant); if (!result) { return(result); } } } } catch (Exception e) { result.EmpileErreur(new CErreurException(e)); } finally { try { liste.ContexteDonnee.EnforceConstraints = bOldEnforce; } catch { if (liste.ContexteDonnee.HasErrors) { foreach (DataTable table in liste.ContexteDonnee.Tables) { if (table.HasErrors) { foreach (DataRow row in table.Rows) { if (row.HasErrors) { string strKey = ""; foreach (DataColumn col in table.PrimaryKey) { strKey += row[col].ToString() + "/"; } result.EmpileErreur("Error while deleting (" + table.TableName + "[" + strKey + "] : " + row.RowError); } } } } } } } return(result); }