/// //////////////////////////////////////////
        public CResultAErreur Update(CContexteDonneesSynchroSecondaire donneesSecondaires)
        {
            CResultAErreur result = CResultAErreur.True;

            //Met à jour les tables;
            foreach (DataTable tableSecondaire in donneesSecondaires.Tables)
            {
                if (m_mappeurTablesToClass.IsSynchronisable(tableSecondaire.TableName))
                {
                    DataTable tableDest  = Tables[tableSecondaire.TableName];
                    string    strPrimKey = tableDest.PrimaryKey[0].ColumnName;

                    foreach (DataRow rowSecondaire in tableSecondaire.Rows)
                    {
                        object obj = rowSecondaire[CSc2iDataConst.c_champIdSynchro];
                        if (m_tableAjouts[tableSecondaire.TableName + "_" + rowSecondaire[strPrimKey].ToString()] == null)
                        //Ce n'est pas un élément ajouté
                        {
                            if (obj is int && ((int)obj) >= donneesSecondaires.IdSynchro)
                            {
                                DataRow rowToUpdate = tableDest.Rows.Find(rowSecondaire[strPrimKey]);
                                if (rowToUpdate != null)
                                {
                                    DataRow rowDest = rowToUpdate;
                                    CopyRow(rowSecondaire, rowDest, false);
                                }
                            }
                        }
                    }
                }
            }
            return(result);
        }
        /// //////////////////////////////////////////
        ///<summary>
        ///Ajoute les nouveaux éléments à partir du domaine Secondaire
        ///</summary>
        public CResultAErreur AjouteNouveaux(CContexteDonneesSynchroSecondaire donneesSecondaires)
        {
            CResultAErreur result          = CResultAErreur.True;
            ArrayList      lst             = donneesSecondaires.GetTablesOrderInsert();
            DataTable      tableEntreesLog = donneesSecondaires.GetTableSafe(CEntreeLogSynchronisation.c_nomTable);

            foreach (DataTable table in lst)
            {
                if (m_mappeurTablesToClass.IsSynchronisable(table.TableName))
                {
                    //int nIdMaxInSecondaire = (int)table.ExtendedProperties[CContexteDonneesSynchroSecondaire.c_extMaxIdInBase];
                    //int nIdMaxInMain = (int)table.ExtendedProperties[CContexteDonneesSynchroSecondaire.c_extMaxIdInBase];
                    int       nNextId   = 0;            //Math.Max(nIdMaxInMain, nIdMaxInSecondaire)+1;
                    DataTable tableDest = Tables[table.TableName];
                    DataView  view      = new DataView(tableEntreesLog);
                    string    strFiltre = CEntreeLogSynchronisation.c_champTable + "='" + table.TableName + "'";
                    view.RowFilter = strFiltre;
                    foreach (DataRowView row in view)
                    {
                        CEntreeLogSynchronisation entree = new CEntreeLogSynchronisation(row.Row);
                        if (entree.TypeModif == CEntreeLogSynchronisation.TypeModifLogSynchro.tAdd)
                        {
                            CObjetDonneeAIdNumerique obj = entree.GetObjet();
                            DataRow newRow = CopieToNew(obj.Row, tableDest, nNextId);
                            nNextId++;
                            m_mapOldRowToNewRow[obj.Row.Row] = newRow;
                            m_tableAjouts[table.TableName + "_" + obj.Id] = "";
                        }
                    }
                }
            }
            return(result);
        }
        /// //////////////////////////////////////////
        public CResultAErreur Delete(CContexteDonneesSynchroSecondaire donneesSecondaires)
        {
            CResultAErreur result = CResultAErreur.True;
            ArrayList      lst    = donneesSecondaires.GetTablesOrderDelete();

            DataTable tableEntreesLog = donneesSecondaires.GetTableSafe(CEntreeLogSynchronisation.c_nomTable);

            foreach (DataTable table in lst)
            {
                if (m_mappeurTablesToClass.IsSynchronisable(table.TableName))
                {
                    DataTable tableDest = Tables[table.TableName];
                    DataView  view      = new DataView(tableEntreesLog);
                    string    strFiltre = CEntreeLogSynchronisation.c_champTable + "='" + table.TableName + "'";
                    view.RowFilter = strFiltre;
                    string strCleMain = tableDest.PrimaryKey[0].ColumnName;
                    foreach (DataRowView row in view)
                    {
                        CEntreeLogSynchronisation entree = new CEntreeLogSynchronisation(row.Row);
                        if (entree.TypeModif == CEntreeLogSynchronisation.TypeModifLogSynchro.tDelete)
                        {
                            DataRow rowDest = tableDest.Rows.Find(entree.IdElement);
                            if (rowDest != null)
                            {
                                rowDest.Delete();
                            }
                        }
                    }
                }
            }
            return(result);
        }
        /// ////////////////////////////////////////////////////////////////////////////////////
        public CResultAErreur WriteChanges(CContexteDonneesSynchroSecondaire donneesSecondaires)
        {
            CResultAErreur result = base.SaveAll(true);

            if (!result)
            {
                return(result);
            }


            //Crée une table des conversions d'id par table
            Hashtable mapTablesOldToNew = new Hashtable();
            Hashtable mapTablesNewToOld = new Hashtable();
            Hashtable mapMaxParTable    = new Hashtable();

            FillMapsId(mapTablesOldToNew, mapTablesNewToOld, mapMaxParTable);

            ChangeOldIdParNew(donneesSecondaires, mapTablesOldToNew, mapTablesNewToOld, mapMaxParTable);

            return(result);
        }
        /// //////////////////////////////////////////////////////////////////
        //le result du dataset contient le dataset à appliquer à la base secondaire
        public CResultAErreur PutSecondaryIntoMain(CContexteDonneesSynchroSecondaire dsSecondaire)
        {
            CResultAErreur result = CResultAErreur.True;

            //Répercute les modifs de la base secondaire sur la base primaire
            using (CContexteDonneesSynchroMain donneesMain = new CContexteDonneesSynchroMain(IdSession, true))
            {
                IDatabaseConnexionSynchronisable connexionMain;
                connexionMain = (IDatabaseConnexionSynchronisable)CSc2iDataServer.GetInstance().GetDatabaseConnexion(IdSession, m_strIdConnexion);

                int nIdSyncMain = connexionMain.IdSyncSession;



                result = donneesMain.ChargeDonneesAMettreAJour(dsSecondaire);

                if (result)
                {
                    result = donneesMain.AjouteNouveaux(dsSecondaire);
                }
                if (result)
                {
                    result = donneesMain.Update(dsSecondaire);
                }
                if (result)
                {
                    result = donneesMain.Delete(dsSecondaire);
                }



                try
                {
                    connexionMain.BeginTrans();
                }
                catch (Exception e)
                {
                    result.EmpileErreur(new CErreurException(e));
                    result.EmpileErreur(I.T("Error while data synchronization|208"));
                    return(result);
                }

                if (result)
                {
                    result = donneesMain.WriteChanges(dsSecondaire);
                }

                //Augmente d'un le numéro de version de la base principale

                if (result)
                {
                    while (connexionMain.IdSyncSession < nIdSyncMain + 2)
                    {
                        connexionMain.IncrementeSyncSession();
                    }

                    result = connexionMain.CommitTrans();

                    result.Data = dsSecondaire;
                }
                else
                {
                    connexionMain.RollbackTrans();
                }
            }
            return(result);
        }
        /// //////////////////////////////////////////////////////////////////
        public CResultAErreur PutMainIntoSecondary(CContexteDonneesSynchro ctxMain)
        {
            CResultAErreur result = CResultAErreur.True;
            IDatabaseConnexionSynchronisable connexionSecondaire = (IDatabaseConnexionSynchronisable)CSc2iDataServer.GetInstance().GetDatabaseConnexion(IdSession, m_strIdConnexion);

            //Toutes les modifs apportées sur la base secondaire doivent porter l'id de synchro
            //Initial de la base secondaire, sinon les modifs font du
            //ping pong entre secondaire et main,
            //Ces modifs ne doivent surtout pas apparaitre
            //lors d'une synchro de sec->main !
            connexionSecondaire.LockSyncSessionLocalTo(connexionSecondaire.LastSyncIdPutInBasePrincipale);

            //Répercute les modifs de la base secondaire sur la base primaire
            using (CContexteDonneesSynchroSecondaire donneeSec = new CContexteDonneesSynchroSecondaire(IdSession, true))
            {
                result = donneeSec.ChargeDonneesAMettreAJour(ctxMain);

                donneeSec.EnforceConstraints = false;
                if (result)
                {
                    result = donneeSec.AjouteNouveaux(ctxMain);
                }
                if (result)
                {
                    result = donneeSec.Update(ctxMain);
                }
                if (result)
                {
                    result = donneeSec.Delete(ctxMain);
                }
                donneeSec.EnforceConstraints = true;
                try
                {
                    connexionSecondaire.BeginTrans();
                }
                catch (Exception e)
                {
                    result.EmpileErreur(new CErreurException(e));
                    result.EmpileErreur(I.T("Error while data synchronization|208"));
                    return(result);
                }

                if (result)
                {
                    result = donneeSec.WriteChanges(ctxMain);
                }


                if (result)
                {
                    if (connexionSecondaire.LastSyncIdPutInBasePrincipale == -1)
                    {
                        connexionSecondaire.LastSyncIdPutInBasePrincipale = connexionSecondaire.IdSyncSession;
                    }

                    connexionSecondaire.UnlockSyncSessionLocal();
                    while (connexionSecondaire.IdSyncSession < ctxMain.IdSynchro)
                    {
                        connexionSecondaire.IncrementeSyncSession();
                    }

                    connexionSecondaire.LastSyncIdVueDeBasePrincipale = ctxMain.IdSynchro == -1?0:ctxMain.IdSynchro;

                    connexionSecondaire.CommitTrans();
                }

                if (!result)
                {
                    connexionSecondaire.RollbackTrans();
                }
            }
            return(result);
        }
        /// ////////////////////////////////////////////////////////////////////////////////////
        private void ChangeOldIdParNew(CContexteDonneesSynchroSecondaire donneesSecondaires, Hashtable mapTablesOldToNew, Hashtable mapTablesNewToOld, Hashtable mapMaxParTable)
        {
            ArrayList           lst             = donneesSecondaires.GetTablesOrderInsert();
            CListeObjetsDonnees listeEntreesLog = new CListeObjetsDonnees(donneesSecondaires, typeof(CEntreeLogSynchronisation));

            listeEntreesLog.InterditLectureInDB = true;
            foreach (DataTable table in lst)
            {
                string strTable = table.TableName;
                if (mapMaxParTable[strTable] != null)
                {
                    //DataTable table = donneesSecondaires.Tables[strTable];
                    string    strPrim       = table.PrimaryKey[0].ColumnName;
                    int       nIndice       = (int)mapMaxParTable[strTable] + 1;
                    Hashtable tableOldToNew = (Hashtable)mapTablesOldToNew[strTable];
                    Hashtable tableIdOriginauxDansSecondaire = new Hashtable();

                    //Commence par renumeroter les indices des nouveaux éléments
                    //pour être sur de ne pas affecter à un élément un id déjà existant
                    foreach (DataRow row in tableOldToNew.Keys)
                    {
                        tableIdOriginauxDansSecondaire[row] = row[strPrim];
                        row[strPrim] = nIndice;
                        nIndice++;
                    }

                    foreach (DataRow row in tableOldToNew.Keys)
                    {
                        DataRow newRowPrim = (DataRow)tableOldToNew[row];
                        int     nNewId     = (int)newRowPrim[strPrim];
                        int     nIdOriginalDansSecondaire = (int)tableIdOriginauxDansSecondaire[row];
                        if (nNewId != nIdOriginalDansSecondaire)

                        /*L'élement a changé d'id. On va donc en créer
                         * un nouveau avec le nouvel id, modifier les liens fils
                         * et supprimer l'ancien
                         * */
                        {
                            //Crée la nouvelle ligne (avec le bon id) (copie de la ligne d'origine)
                            DataRow newRowSec = table.NewRow();
                            CopyRow(newRowPrim, newRowSec);
                            table.Rows.Add(newRowSec);

                            //Change l'info de log synchro
                            listeEntreesLog.Filtre = new CFiltreData(
                                CEntreeLogSynchronisation.c_champTable + "=@1 and " +
                                CEntreeLogSynchronisation.c_champIdElement + "=@2 and " +
                                CEntreeLogSynchronisation.c_champType + "=@3",
                                strTable,
                                nIdOriginalDansSecondaire,
                                (int)CEntreeLogSynchronisation.TypeModifLogSynchro.tAdd);
                            if (listeEntreesLog.Count > 0)
                            {
                                CEntreeLogSynchronisation entree = (CEntreeLogSynchronisation)listeEntreesLog[0];
                                entree.IdElement = nNewId;
                            }


                            //Change toutes les liaisons filles sur le nouvel élément
                            foreach (DataRelation rel in table.ChildRelations)
                            {
                                if (rel.ParentColumns.Length == 1 && rel.ParentColumns[0].ColumnName == strPrim)
                                {
                                    foreach (DataRow childRow in row.GetChildRows(rel))
                                    {
                                        childRow[rel.ChildColumns[0].ColumnName] = nNewId;
                                    }
                                }
                            }
                            //Supprime l'ancien élément
                            row.Delete();
                        }
                        else
                        {
                            row[strPrim] = nIdOriginalDansSecondaire;
                        }
                    }
                }
            }
        }