예제 #1
0
        /// //////////////////////////////////////////
        protected CResultAErreur GetFiltre(
            CContexteEvaluationExpression ctx,
            C2iExpression expressionAcces,
            C2iExpression expressionFiltre,
            params C2iExpression[] parametresFiltre)
        {
            CResultAErreur result = CResultAErreur.True;
            //Commence par créer le filtre qui permet d'accéder au type accedé (basé sur le premier paramètre

            /*Pour créer ce filtre, il faut remonter à l'envers depuis le type retourné
             * vers le type source de l'expression.
             * PAr exemple Classement.Lignes depuis lotproduit doit être inversé pour
             * indiquer le lot de produit du classement des lignes
             * (classement.LotProduitOrigine)
             *
             * */
            string        strFiltreToType = "";
            C2iExpression parametre       = expressionAcces;

            ArrayList lstPropsAccedees = new ArrayList();

            /*if (!(ctx.ObjetSource is CObjetDonnee ))
             * {
             *      result.EmpileErreur("La fonction SelectSql ne peut pas être appliquée ici ");
             *      return result;
             * }*/


            Type tp = ctx.ObjetSource.GetType();

            CObjetDonnee objetRacine = (CObjetDonnee)ctx.ObjetSource;


            while (parametre != null)
            {
                string strTable = CContexteDonnee.GetNomTableForType(tp);
                if (strTable == null)
                {
                    result.EmpileErreur(I.T("The SelectSql function cannot be applied on an element @1|210", DynamicClassAttribute.GetNomConvivial(tp)));
                    return(result);
                }
                C2iExpressionChamp champ;
                if (parametre is C2iExpressionChamp)
                {
                    champ = (C2iExpressionChamp)parametre;
                }
                else if (parametre is C2iExpressionObjet && parametre.Parametres2i[0] is C2iExpressionChamp)
                {
                    champ = (C2iExpressionChamp)parametre.Parametres2i[0];
                }
                else
                {
                    result.EmpileErreur(I.T("Error in the SelectSql parameter|211"));
                    return(result);
                }
                CDefinitionProprieteDynamique def = champ.DefinitionPropriete;
                PropertyInfo info = tp.GetProperty(def.NomProprieteSansCleTypeChamp);
                if (info == null)
                {
                    result.EmpileErreur(I.T("The property @1 is not valid for SelectSql(*)|212", def.NomPropriete));
                    return(result);
                }
                //Il faut trouver la propriété de l'élément accedé utilisée pour atteindre le type précédent
                Type tpAccede = null;
                //Si la propriété a l'attribut relation fille, on va trouver l'info
                object[] attribs = info.GetCustomAttributes(typeof(RelationFilleAttribute), true);
                if (attribs.Length != 0)
                {
                    RelationFilleAttribute attr = (RelationFilleAttribute)attribs[0];
                    strFiltreToType = attr.ProprieteFille + "." + strFiltreToType;
                    tpAccede        = attr.TypeFille;
                    strTable        = CContexteDonnee.GetNomTableForType(tpAccede);
                }
                else
                {
                    //Pas une relation fille, est-ce une relation parente ?
                    attribs = info.GetCustomAttributes(typeof(RelationAttribute), true);
                    if (attribs.Length != 0)
                    {
                        if (objetRacine.IsNew())
                        {
                            //L'objet racine est un nouvel objet, il n'est donc pas dans la base,
                            //Donc la requête ne retournera rien !!!. Il faut donc utiliser
                            //le prochain élément comme objetRacine
                            objetRacine = (CObjetDonnee)info.GetGetMethod().Invoke(objetRacine, new object[0]);
                            if (objetRacine != null)
                            {
                                tpAccede = objetRacine.GetType();
                            }
                        }
                        else
                        {
                            RelationAttribute attr = (RelationAttribute)attribs[0];
                            strFiltreToType = attr.GetInfoRelation(strTable).RelationKey + "." + strFiltreToType;
                            tpAccede        = info.PropertyType;
                            strTable        = CContexteDonnee.GetNomTableForType(tpAccede);
                        }
                    }
                    else
                    {
                        // on est mal, impossible de savoir à quoi on fait référence !
                        result.EmpileErreur(I.T("The property @1 is not valid for a SelectSql operation|213", def.NomPropriete));
                        return(result);
                    }
                }
                tp = tpAccede;
                if (parametre is C2iExpressionObjet)
                {
                    parametre = parametre.Parametres2i[1];
                }
                else
                {
                    parametre = null;
                }
            }

            //Crée le filtre
            CObjetDonnee      objetSource = objetRacine;
            CFiltreDataAvance filtre      = new CFiltreDataAvance(CContexteDonnee.GetNomTableForType(tp), "");
            int nCle = 1;

            foreach (string strCle in objetSource.GetChampsId())
            {
                filtre.Filtre += strFiltreToType + strCle + "=@" + nCle.ToString();
                nCle++;
                filtre.Parametres.Add(objetSource.Row[strCle]);
            }

            //Voila, on n'a plus qu'à combiner avec le filtre demandé
            //evaluation du paramètre 1
            result = expressionFiltre.Eval(ctx);
            if (!result)
            {
                result.EmpileErreur(I.T("Error in SelectSql filter|214"));
                return(result);
            }
            if (result.Data.ToString().Trim() != "")
            {
                CFiltreDataAvance filtre2 = new CFiltreDataAvance(CContexteDonnee.GetNomTableForType(tp), result.Data.ToString());
                //L'analyseur de filtre ne comprend pas la syntaxe [CHAMP].[Champ], mais comprend
                //[Champ.Champ], il faut donc remplacer tous les ].[ par des .
                filtre2.Filtre = filtre2.Filtre.Replace("].[", ".");
                foreach (C2iExpression expression in parametresFiltre)
                {
                    result = expression.Eval(ctx);
                    if (!result)
                    {
                        return(result);
                    }
                    filtre2.Parametres.Add(result.Data);
                }
                try
                {
                    filtre = (CFiltreDataAvance)CFiltreData.GetAndFiltre(filtre, filtre2);
                }
                catch (Exception e)
                {
                    result.EmpileErreur(new CErreurException(e));
                    result.EmpileErreur(I.T("Error during the creation of a SelectSql filter|215"));
                    return(result);
                }
            }
            result.Data = filtre;
            return(result);
        }