/////////////////////////////////////////////////////////////////////////////////////////////////
        private void ReadDependanceParente(
            string strPropriete,
            CListeObjetsDonnees lstSource,
            CListeObjetsDonnees.CArbreProps arbre,
            CInfoRelation relation)
        {
            int          nNbTotal = lstSource.Count;
            string       strKey   = relation.RelationKey;
            Type         tp       = null;
            PropertyInfo info     = lstSource.TypeObjets.GetProperty(strPropriete);

            if (info == null)
            {
                return;
            }
            tp = info.PropertyType;
            if (tp != null && typeof(CObjetDonneeAIdNumerique).IsAssignableFrom(tp))
            {
                //Crée les paquets
                ArrayList lstPaquets            = new ArrayList();
                Hashtable tableIdsParentTraites = new Hashtable();
                int       nPaquet          = 0;
                string    strChampFille    = relation.ChampsFille[0];
                string    strPaquetEnCours = "";
                int       nNbInPaquet      = 0;
                for (int n = 0; n < lstSource.View.Count; n++)
                {
                    DataRow row    = lstSource.View.GetRow(n);
                    string  strCle = row[strChampFille].ToString();
                    if (strCle != "")
                    {
                        if (tableIdsParentTraites[strCle] == null)
                        {
                            tableIdsParentTraites[strCle] = true;
                            strPaquetEnCours += strCle + ",";
                            nNbInPaquet++;
                            if (nNbInPaquet >= CListeObjetsDonnees.c_nNbLectureParLotFils)
                            {
                                strPaquetEnCours = "(" + strPaquetEnCours.Substring(0, strPaquetEnCours.Length - 1) + ")";
                                lstPaquets.Add(strPaquetEnCours);
                                strPaquetEnCours = "";
                                nNbInPaquet      = 0;
                            }
                        }
                    }
                }
                if (strPaquetEnCours.Length > 0)
                {
                    strPaquetEnCours = "(" + strPaquetEnCours.Substring(0, strPaquetEnCours.Length - 1) + ")";
                    lstPaquets.Add(strPaquetEnCours);
                }

                //Lit les relations par paquet
                int nNbPaquets = lstPaquets.Count;
                for (nPaquet = 0; nPaquet < nNbPaquets; nPaquet++)
                {
                    string strPaquet = (string)lstPaquets[nPaquet];
                    if (strPaquet != "()")
                    {
                        CListeObjetsDonnees listeParent = new CListeObjetsDonnees(lstSource.ContexteDonnee, tp);
                        listeParent.ModeSansTri     = true;
                        listeParent.PreserveChanges = true;
                        listeParent.Filtre          = new CFiltreData(relation.ChampsParent[0] + " in " + strPaquet);
                        listeParent.AssureLectureFaite();
                        //Indique que les lignes ont été lues
                        //Stef 2/12/2011 : non, on n'indique pas que c'est lu puisqu'il
                        //s'agit de dépendances parentes !
                        //Ca pose le problème suivant : si on est sur une table hiérarchique,
                        //lorsqu'on lit le parent (d'un projet par exemple), le fait de
                        //dire que les dépendances sont lues implique qu'on indique
                        //qu'on a lu les fils.
                        //De ma compréhension à ce jour, on ne gère pas de colonne
                        //indiquant si la dépendance a été chargé pour des dépendances
                        //parentes

                        /*if ( lstSource.View.Table.Columns[strKey] != null )
                         * {
                         *      for ( int nRow = 0; nRow < lstSource.View.Count; nRow++ )
                         *      {
                         *              CContexteDonnee.ChangeRowSansDetectionModification ( lstSource.View.GetRow ( nRow ), strKey, true );
                         *      }
                         * }*/
                        listeParent.ReadDependances(arbre);
                    }
                }
            }
        }
예제 #2
0
        /////////////////////////////////////////////////////////////
        private void AddFields(Type leType, Hashtable tableIdsDefinisDansTableAttribute, Hashtable tableIds, bool bRelationsOnly)
        {
            if (leType == null)
            {
                return;
            }
            if (!bRelationsOnly)
            {
                //Relation vers la table Versions
                #region Relation vers la table versions
                if (!typeof(IObjetSansVersion).IsAssignableFrom(leType))
                {
                    CInfoChampTable champVersion = new CInfoChampTable(CSc2iDataConst.c_champIdVersion,
                                                                       typeof(int),
                                                                       0,
                                                                       false,
                                                                       false,
                                                                       true,
                                                                       false,
                                                                       true);
                    //Stef 06 10 2009 : le champ version n'est plus indexé seul, il est indexé
                    //avec le champ deleted
                    champVersion.IsIndex   = true;
                    champVersion.Propriete = "IdVersionDatabase";
                    m_listeChamps.Add(champVersion);
                    m_tableChamps[champVersion.NomChamp] = champVersion;

                    //Stef 29/08/2008 : suppression du lien à la version, trop lent !

                    /*CInfoRelation relationVersion = new CInfoRelation(
                     *      CVersionDonnees.c_nomTable,
                     *      NomTable,
                     *      new string[] { CVersionDonnees.c_champId },
                     *      new string[] { champVersion.NomChamp },
                     *      false,
                     *      true,
                     *      true,
                     *      false);
                     * relationVersion.NomConvivial = "Version";
                     * m_listeRelationsParentes.Add(relationVersion);*/

                    CInfoChampTable champIdOriginal = new CInfoChampTable(CSc2iDataConst.c_champOriginalId,
                                                                          typeof(int),
                                                                          0,
                                                                          false,
                                                                          false,
                                                                          true,
                                                                          false,
                                                                          true);
                    champIdOriginal.IsIndex = true;
                    m_listeChamps.Add(champIdOriginal);

                    CInfoChampTable champIsDeleted = new CInfoChampTable(CSc2iDataConst.c_champIsDeleted,
                                                                         typeof(bool),
                                                                         0,
                                                                         false,
                                                                         false,
                                                                         false,
                                                                         false,
                                                                         true);
                    champIsDeleted.Propriete = "IsDeleted";
                    m_listeChamps.Add(champIsDeleted);

                    //Stef 06 10 2009 : le champ version n'est plus indexé seul, il est indexé
                    //avec le champ deleted

                    /*CInfoIndexTable infoIndex = new CInfoIndexTable(
                     *  CSc2iDataConst.c_champIdVersion, CSc2iDataConst.c_champIsDeleted);
                     * m_listeIndexsSupplementaires.Add(infoIndex);*/
                }
            }

            #endregion


            foreach (PropertyInfo property in leType.GetProperties())
            {
                string   strNomConvivial = "";
                object[] attribs;
                attribs = property.GetCustomAttributes(typeof(DynamicFieldAttribute), true);
                //si le champ a l'attribut dynamique, il a un nom convivial
                if (attribs.Length != 0)
                {
                    strNomConvivial = ((DynamicFieldAttribute)attribs[0]).NomConvivial;
                }

                //Attribut TableField
                attribs = property.GetCustomAttributes(typeof(TableFieldPropertyAttribute), true);
                if (attribs.Length == 1 && !bRelationsOnly)
                {
                    TableFieldPropertyAttribute attrib = (TableFieldPropertyAttribute)attribs[0];
                    if (attrib.IsInDb)                    //Ne prend que les champs qui sont dans la base de données
                    {
                        if (property.Name != "IdUniversel" ||
                            leType.GetCustomAttributes(typeof(NoIdUniverselAttribute), true).Length == 0)
                        {
                            if (property.PropertyType == typeof(string) && attrib.Longueur < 1)
                            {
                                throw (new Exception(I.T("The field attribute @1 of class @2 doesn't define a length|168", property.Name, leType.Name)));
                            }
                            bool bIsId = tableIdsDefinisDansTableAttribute[attrib.NomChamp] != null;

                            CInfoChampTable info = new CInfoChampTable(
                                attrib.NomChamp,
                                property.PropertyType,
                                attrib.Longueur,
                                attrib.IsLongString,
                                bIsId,
                                attrib.NullAutorise && !bIsId,
                                attrib.ExclureUpdateStandard,
                                attrib.IsInDb);

                            info.Propriete    = property.Name;
                            info.NomConvivial = strNomConvivial;

                            if (property.GetCustomAttributes(typeof(IndexFieldAttribute), true).Length > 0)
                            {
                                info.IsIndex = true;
                            }

                            if (m_tableChamps[info.NomChamp] == null)
                            {
                                m_listeChamps.Add(info);
                                m_tableChamps[info.NomChamp] = info;
                            }
                            if (bIsId)
                            {
                                tableIds[info.NomChamp] = info;
                            }
                        }
                    }
                }

                //Attribut Relation
                if (bRelationsOnly)
                {
                    m_bIsRelationsInitialisees = true;
                    attribs = property.GetCustomAttributes(typeof(RelationAttribute), true);
                    if (attribs.Length != 0)
                    {
                        RelationAttribute relAttrib        = (RelationAttribute)attribs[0];
                        CStructureTable   structureParente = GetStructure(CContexteDonnee.GetTypeForTable(relAttrib.TableMere));
                        if (relAttrib.TableMere == NomTable)                        //Pour les tables autoliées
                        {
                            structureParente = this;
                        }
                        //Si la structure parente est moi-même, les champs Id n'ont pas encore
                        //été renseignés. Il y a donc un contrôle en moins sur les tables à lien récursif
                        if (structureParente.ChampsId != null && relAttrib.ChampsFils.Length != relAttrib.ChampsParent.Length)
                        {
                            throw new Exception(I.T("The relation between the table @1 and the parental table @2 doesn't have the right number of link fields|169", NomTable, relAttrib.TableMere));
                        }

                        int nIndexCle = 0;
                        foreach (string strChamp in relAttrib.ChampsFils)
                        {
                            bool            bIsId = tableIdsDefinisDansTableAttribute[strChamp] != null;
                            CInfoChampTable info  = new CInfoChampTable(
                                strChamp,
                                structureParente.GetChamp(relAttrib.ChampsParent[nIndexCle]).TypeDonnee,
                                structureParente.GetChamp(relAttrib.ChampsParent[nIndexCle]).Longueur,
                                false,
                                bIsId,
                                !relAttrib.Obligatoire,
                                false,
                                true);
                            info.IsIndex = relAttrib.Index;

                            //13/3/2005 : les deux lignes suivants avaient été enlevées. Pourquoi ?
                            //En tout cas, moi j'en ai besoin pour pouvoir tester
                            //Les attributs de la propriété
                            //20/4/2005
                            //Ca avait été enlevé car le champ pointe sur le type de donnée
                            //de la clé (un entier en général), c'est un champ qui ne doit pas être affiché
                            //dans les listes de propriétés , c'est juste un champ de la table

                            /*info.Propriete = property.Name;
                             * info.NomConvivial = strNomConvivial;*/
                            /* 9/5/2005, si on souhaite trouver la propriété correspondantes,
                             * il faut parcourir les relations et regarder les propriétés des relations
                             * */
                            nIndexCle++;
                            if (m_tableChamps[info.NomChamp] == null)
                            {
                                m_listeChamps.Add(info);
                                m_tableChamps[info.NomChamp] = info;
                            }
                            if (tableIdsDefinisDansTableAttribute[strChamp] != null)
                            {
                                //Ce champ fait partie de la clé de l'objet
                                tableIds[info.NomChamp] = info;
                            }
                        }
                        CInfoRelation infoRelation = new CInfoRelation(
                            relAttrib.TableMere,
                            NomTable,
                            relAttrib.ChampsParent,
                            relAttrib.ChampsFils,
                            relAttrib.Obligatoire,
                            relAttrib.Composition,
                            relAttrib.Index,
                            relAttrib.PasserLesFilsANullLorsDeLaSuppression,
                            relAttrib.DeleteEnCascadeManuel);
                        infoRelation.IsInDb             = relAttrib.IsInDb;
                        infoRelation.IsClustered        = relAttrib.IsCluster;
                        infoRelation.NomConvivial       = strNomConvivial;
                        infoRelation.Propriete          = property.Name;
                        infoRelation.NePasClonerLesFils = relAttrib.NePasClonerLesFils;
                        m_listeRelationsParentes.Add(infoRelation);
                    }

                    //Attribut RelationFille
                    attribs = property.GetCustomAttributes(typeof(RelationFilleAttribute), true);
                    if (attribs.Length != 0)
                    {
                        RelationFilleAttribute relFille             = (RelationFilleAttribute)attribs[0];
                        PropertyInfo           propParenteDansFille = relFille.TypeFille.GetProperty(relFille.ProprieteFille);
                        if (propParenteDansFille == null)
                        {
                            throw new Exception(I.T("The @1 type defines a child relation on the child property @2.@3 which doesn't exist|170", leType.Name, relFille.TypeFille.Name, relFille.ProprieteFille));
                        }
                        //Récupère les infos de la relation
                        attribs = propParenteDansFille.GetCustomAttributes(typeof(RelationAttribute), true);
                        if (attribs.Length != 1)
                        {
                            throw new Exception(I.T("The @1 type defines a child relation on the child property @2.@3 which doesn't define a parental relation|171", leType.Name, relFille.TypeFille.Name, relFille.ProprieteFille));
                        }
                        RelationAttribute relInfo = (RelationAttribute)attribs[0];
                        //Récupère le nom de la table fille
                        attribs = relFille.TypeFille.GetCustomAttributes(typeof(TableAttribute), true);
                        if (attribs.Length != 1)
                        {
                            throw new Exception(I.T("The @1 type define a child relation on the @2 type which doesn't define a table|172", leType.Name, relFille.TypeFille.Name));
                        }
                        object[] attr = property.GetCustomAttributes(typeof(DynamicChildsAttribute), false);
                        if (attr.Length > 0)
                        {
                            strNomConvivial = ((DynamicChildsAttribute)attr[0]).NomConvivial;
                        }
                        CInfoRelation infoRelation = new CInfoRelation(
                            NomTable,
                            ((TableAttribute)attribs[0]).NomTable,
                            relInfo.ChampsParent,
                            relInfo.ChampsFils,
                            relInfo.Obligatoire,
                            relInfo.Composition,
                            relInfo.Index,
                            relInfo.PasserLesFilsANullLorsDeLaSuppression,
                            relInfo.DeleteEnCascadeManuel);
                        infoRelation.NomConvivial       = strNomConvivial;
                        infoRelation.Propriete          = property.Name;
                        infoRelation.NePasClonerLesFils = relInfo.NePasClonerLesFils;
                        m_listeRelationsFilles.Add(infoRelation);
                    }
                }
            }
            ///Relations TypeID
            foreach (RelationTypeIdAttribute relTypeId in CContexteDonnee.RelationsTypeIds)
            {
                if (relTypeId.IsAppliqueToType(leType))
                {
                    m_listeRelationsFillesTypeId.Add(relTypeId);
                }
            }
            //AddFields ( leType.BaseType, tableIdsDefinisDansTableAttribute, tableIds );
        }
        /////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Lit les dépendances filles du type de donné
        /// </summary>
        /// <returns></returns>
        private void ReadDependanceFille(
            string strPropriete,
            CListeObjetsDonnees lstSource,
            CListeObjetsDonnees.CArbreProps arbre,
            CInfoRelation relation,
            List <string> listePaquets)
        {
            CResultAErreur result  = CResultAErreur.True;
            Type           tpFille = null;
            PropertyInfo   info    = lstSource.TypeObjets.GetProperty(strPropriete);

            if (info == null)
            {
                return;
            }

            object[] attrs = info.GetCustomAttributes(typeof(RelationFilleAttribute), true);
            if (attrs == null || attrs.Length < 0)
            {
                return;
            }
            tpFille = ((RelationFilleAttribute)attrs[0]).TypeFille;

            DataTable table = lstSource.ContexteDonnee.GetTableSafe(lstSource.NomTable);

            //S'assure que la table fille est chargée
            lstSource.ContexteDonnee.GetTableSafe(relation.TableFille);
            string     strKey        = relation.RelationKey;
            DataColumn colDependance = table.Columns[strKey];


            if (listePaquets == null)
            {
                listePaquets = lstSource.GetPaquetsPourLectureFils(relation.ChampsParent[0], colDependance);
            }
            int nNbPaquets = listePaquets.Count;

            //Lit les relations par paquet
            for (int nPaquet = 0; nPaquet < nNbPaquets; nPaquet++)
            {
                string strPaquet = (string)listePaquets[nPaquet];
                if (strPaquet.Length > 0)
                {
                    CListeObjetsDonnees listeFille = new CListeObjetsDonnees(lstSource.ContexteDonnee, tpFille);
                    listeFille.Filtre = new CFiltreData(relation.ChampsFille[0] + " in " + strPaquet);
                    if (arbre.Filtre.Length > 0)
                    {
                        listeFille.Filtre.Filtre += " and " + arbre.Filtre;
                    }
                    listeFille.ModeSansTri     = true;
                    listeFille.PreserveChanges = true;
                    listeFille.AssureLectureFaite();
                    int nMax = Math.Min(lstSource.Count, (nPaquet + 1) * CListeObjetsDonnees.c_nNbLectureParLotFils);


                    if (colDependance != null && arbre.Filtre.Length == 0)
                    {
                        //Indique que les lignes ont été lues
                        for (int nRow = nPaquet * CListeObjetsDonnees.c_nNbLectureParLotFils; nRow < nMax; nRow++)
                        {
                            DataRow      row      = lstSource.View.GetRow(nRow);
                            DataRowState oldState = row.RowState;
                            row[colDependance] = true;
                            if (oldState == DataRowState.Unchanged)
                            {
                                row.AcceptChanges();
                            }
                        }
                    }
                    listeFille.ReadDependances(arbre);
                }
            }
        }
예제 #4
0
        //-------------------------------------
        /// <summary>
        /// Retourne tous les fils qui étaient affecté à l'objet à l'époque
        /// </summary>
        /// <param name="objet"></param>
        /// <param name="relationFille"></param>
        /// <returns></returns>
        public int[] GetIdsChildsHistoriques(CObjetDonneeAIdNumerique objet, CInfoRelation relationFille)
        {
            Type tpFils = CContexteDonnee.GetTypeForTable(relationFille.TableFille);

            if (!typeof(CObjetDonneeAIdNumerique).IsAssignableFrom(tpFils))
            {
                return(new int[0]);
            }
            CChampPourVersionInDb champFille = new CChampPourVersionInDb(relationFille.ChampsFille[0], "");
            //Recherche toutes les modifications de la propriété fille
            CListeObjetsDonnees listeModifsFilles = new CListeObjetsDonnees(objet.ContexteDonnee, typeof(CVersionDonneesObjetOperation));

            listeModifsFilles.Filtre = new CFiltreDataAvance(
                CVersionDonneesObjetOperation.c_nomTable,
                CVersionDonneesObjetOperation.c_champChamp + "=@1 and " +
                CVersionDonneesObjetOperation.c_champTypeChamp + "=@2 and " +
                CVersionDonneesObjet.c_nomTable + "." +
                CVersionDonneesObjet.c_champTypeElement + "=@3 and " +
                CVersionDonneesObjet.c_nomTable + "." +
                CVersionDonnees.c_nomTable + "." +
                CVersionDonnees.c_champTypeVersion + "=@4 and " +
                CVersionDonneesObjet.c_nomTable + "." +
                CVersionDonnees.c_champId + ">=@5",
                champFille.FieldKey,
                champFille.TypeChampString,
                tpFils.ToString(),
                (int)CTypeVersion.TypeVersion.Archive,
                Id);
            listeModifsFilles.Tri = CVersionDonneesObjetOperation.c_champId + " desc";
            listeModifsFilles.ReadDependances("VersionObjet");

            ArrayList lstFils = new ArrayList();

            //Remplit la liste des fils avec les fils actuels
            //Récupère la liste de tous les fils actuels
            //et supprimés depuis. En effet, un element supprimé depuis cette version mais qui est
            //toujours lié à l'objet était donc lié à l'objet à l'époque
            C2iRequeteAvancee requete = new C2iRequeteAvancee(-1);

            requete.TableInterrogee = relationFille.TableFille;
            C2iChampDeRequete champDeRequete = new C2iChampDeRequete("ID",
                                                                     new CSourceDeChampDeRequete(objet.ContexteDonnee.GetTableSafe(relationFille.TableFille).PrimaryKey[0].ColumnName),
                                                                     typeof(int),
                                                                     OperationsAgregation.None,
                                                                     true);

            requete.ListeChamps.Add(champDeRequete);
            CFiltreData filtre = new CFiltreData(relationFille.ChampsFille[0] + "=@1 and (" +
                                                 CSc2iDataConst.c_champIdVersion + " is null or " +
                                                 CSc2iDataConst.c_champIdVersion + ">=@2)",
                                                 objet.Id,
                                                 Id);

            filtre.IgnorerVersionDeContexte = true;
            requete.FiltreAAppliquer        = filtre;
            CResultAErreur result = requete.ExecuteRequete(objet.ContexteDonnee.IdSession);

            if (result)
            {
                foreach (DataRow row in ((DataTable)result.Data).Rows)
                {
                    lstFils.Add(row[0]);
                }
            }


            foreach (CVersionDonneesObjetOperation data in listeModifsFilles)
            {
                if (data.GetValeur() is int && (int)data.GetValeur() == objet.Id)
                {
                    if (!lstFils.Contains(data.VersionObjet.IdElement))
                    {
                        lstFils.Add(data.VersionObjet.IdElement);
                    }
                }
                else
                {
                    lstFils.Remove(data.VersionObjet.IdElement);
                }
            }

            //Toutes les entités créées après la version ont également été ajoutées,
            //Donc n'y étaient pas
            if (lstFils.Count > 0)
            {
                StringBuilder builder = new StringBuilder();
                foreach (int nId in lstFils)
                {
                    builder.Append(nId.ToString());
                    builder.Append(",");
                }
                string strIds = builder.ToString();
                strIds  = strIds.Substring(0, strIds.Length - 1);
                requete = new C2iRequeteAvancee(-1);
                requete.TableInterrogee  = CVersionDonneesObjet.c_nomTable;
                requete.FiltreAAppliquer = new CFiltreData(
                    CVersionDonneesObjet.c_champIdElement + " in (" + strIds + ") and " +
                    CVersionDonneesObjet.c_champTypeElement + "=@1 and " +
                    CVersionDonneesObjet.c_champTypeOperation + "=@2 and " +
                    CVersionDonnees.c_champId + ">=@3",
                    tpFils.ToString(),
                    CTypeOperationSurObjet.TypeOperation.Ajout,
                    Id);
                requete.FiltreAAppliquer.IgnorerVersionDeContexte = true;
                requete.ListeChamps.Add(new C2iChampDeRequete("Id",
                                                              new CSourceDeChampDeRequete(CVersionDonneesObjet.c_champIdElement),
                                                              typeof(int),
                                                              OperationsAgregation.None,
                                                              true));
                result = requete.ExecuteRequete(ContexteDonnee.IdSession);
                if (result)
                {
                    foreach (DataRow row in ((DataTable)result.Data).Rows)
                    {
                        lstFils.Remove(row[0]);
                    }
                }
            }
            return((int[])lstFils.ToArray(typeof(int)));
        }