public DrillContext(
     MdxActionContext mdxContext,
     DrillActionContainer rootAction)
 {
     this.MdxContext = mdxContext;
     this.RootAction = rootAction;
 }
        protected override MdxObject ProcessCore(MdxObject mdx, MdxActionContext context)
        {
            MdxExpression expr = mdx as MdxExpression;

            if (expr == null)
            {
                return(mdx);
            }

            /*
             * Формируем запрос вида:
             *    SELECT
             * HIERARCHIZE(
             * FILTER(
             * DRILLUPMEMBER(HIERARCHIZE(CROSSJOIN(DRILLDOWNMEMBER({[Customer].[Customer Geography].[Country].[Australia]},[Customer].[Customer Geography].[Country].&[Australia]),{[Sales Territory].[Sales Territory].[Sales Territory Group].Members})),[Customer].[Customer Geography].[State-Province].&[NSW]&[AU])
             * ,
             * IsSibling([Customer].[Customer Geography].CURRENTMEMBER,[Customer].[Customer Geography].[State-Province].&[NSW]&[AU].PARENT)
             * )
             * ) ON 0,
             * HIERARCHIZE(HIERARCHIZE(head({[Product].[Product Categories].[Category].Members},10))) ON 1
             * FROM [Adventure Works]
             */
            MdxExpression drillUpExpr = new MdxFunctionExpression(
                "DRILLUPMEMBER",
                new MdxExpression[]
            {
                expr,
                new MdxObjectReferenceExpression(context.MemberUniqueName)
            });

            return(new MdxFunctionExpression(
                       "FILTER",
                       new MdxExpression[]
            {
                drillUpExpr,
                new MdxFunctionExpression(
                    "IsSibling",
                    new MdxExpression[]
                {
                    new MdxPropertyExpression(
                        new MdxObjectReferenceExpression(context.HierarchyUniqueName),
                        "CURRENTMEMBER"),
                    new MdxPropertyExpression(
                        new MdxObjectReferenceExpression(context.MemberUniqueName),
                        "PARENT")
                }
                    )
            }));
        }
        protected override MdxObject ProcessCore(MdxObject mdx, MdxActionContext context)
        {
            MdxExpression expr = mdx as MdxExpression;

            if (expr == null)
            {
                return(mdx);
            }

            return(new MdxFunctionExpression(
                       "DRILLUPMEMBER",
                       new MdxExpression[]
            {
                expr,
#warning Use context.MemberUniqueName instead this.MemberUniqueName?
                new MdxObjectReferenceExpression(context.MemberUniqueName)
            }));
        }
        protected override MdxObject ProcessCore(MdxObject mdx, MdxActionContext context)
        {
            MdxExpression expr = mdx as MdxExpression;

            if (expr == null)
            {
                return(mdx);
            }

            /*
             * WITH
             * MEMBER [Сценарий].[Сценарии].[Сценарий] AS 'iif (1,[Сценарий].[Сценарии].&[План],[Сценарий].[Сценарии].&[Факт])'
             * SELECT
             * HIERARCHIZE({Descendants([Период].[ГКМ].[Год].&[2008],[Период].[ГКМ].[Месяц])}) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON 0,
             * HIERARCHIZE(
             * // ФИЛЬТР
             * FILTER
             * (
             *  DRILLDOWNMEMBER(FILTER(DRILLDOWNMEMBER(Crossjoin({StrToSet('[Персона].[Персонал].[Весь персонал]')},{[Номенклатура].[Вид-Группа-Номенклатура].[Вид].&[Технологические работы].Children}),[Номенклатура].[Вид-Группа-Номенклатура].[Группа].&[Абонентское и гарантийное обслуживание]),(((not ([Номенклатура].[Вид-Группа-Номенклатура].CURRENTMEMBER is [Номенклатура].[Вид-Группа-Номенклатура].[Группа].&[Абонентское и гарантийное обслуживание]))AND(not IsSibling([Номенклатура].[Вид-Группа-Номенклатура].CURRENTMEMBER,[Номенклатура].[Вид-Группа-Номенклатура].[Группа].&[Абонентское и гарантийное обслуживание])))AND(not IsAncestor([Номенклатура].[Вид-Группа-Номенклатура].CURRENTMEMBER,[Номенклатура].[Вид-Группа-Номенклатура].[Группа].&[Абонентское и гарантийное обслуживание])))),[Номенклатура].[Вид-Группа-Номенклатура].[Номенклатура].&[0x80000000000000DE])
             * ,
             * // УСЛОВИЕ ДЛЯ ФИЛЬТРА
             *  (
             *  // ПЕРВОЕ УСЛОВИЕ - Убираем сам элемент если у него количество дочерних не равно 0
             *                          not (
             *                                          ([Номенклатура].[Вид-Группа-Номенклатура].CURRENTMEMBER is [Номенклатура].[Вид-Группа-Номенклатура].[Номенклатура].&[0x80000000000000DE])
             *                                  and ([Номенклатура].[Вид-Группа-Номенклатура].[Номенклатура].&[0x80000000000000DE].Children.Count <> 0)
             *                                  )
             *                  AND
             *  // ВТОРОЕ УСЛОВИЕ - Убираем соседей, кроме самого элемента
             *                          not (
             *                                          IsSibling([Номенклатура].[Вид-Группа-Номенклатура].CURRENTMEMBER,[Номенклатура].[Вид-Группа-Номенклатура].[Номенклатура].&[0x80000000000000DE])
             *                                  and
             *                                          not([Номенклатура].[Вид-Группа-Номенклатура].CURRENTMEMBER is [Номенклатура].[Вид-Группа-Номенклатура].[Номенклатура].&[0x80000000000000DE])
             *                                  )
             *                  AND
             *  // ТРЕТЬЕ УСЛОВИЕ - Убираем предков элемента
             *                          not IsAncestor([Номенклатура].[Вид-Группа-Номенклатура].CURRENTMEMBER,[Номенклатура].[Вид-Группа-Номенклатура].[Номенклатура].&[0x80000000000000DE])
             *                  // ЧЕТВЕРТОЕ УСЛОВИЕ - Оставляем только потомков
             *                  AND
             *                  (
             *                          IsAncestor([Номенклатура].[Вид-Группа-Номенклатура].[Номенклатура].&[0x80000000000000DE], [Номенклатура].[Вид-Группа-Номенклатура].CURRENTMEMBER) or ([Номенклатура].[Вид-Группа-Номенклатура].CURRENTMEMBER is [Номенклатура].[Вид-Группа-Номенклатура].[Номенклатура].&[0x80000000000000DE])
             *                  )
             *  )
             * )
             *
             * ) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON 1
             *
             * FROM [Бюджет]
             * WHERE(
             * [Measures].[Количество],
             * [Статья].[Статьи].&[и_Ресурсы_Загрузка],
             * [ЦФО].[Менеджмент].&[У-5],
             * [Подразделение].[Подразделения].[Все подразделения].UNKNOWNMEMBER,
             * [Сценарий].[Сценарии].&[План]
             * )
             */
            MdxExpression drillDownExpr = new MdxFunctionExpression(
                "DRILLDOWNMEMBER",
                new MdxExpression[]
            {
                expr,
                new MdxObjectReferenceExpression(context.MemberUniqueName)
            });

            return(new MdxFunctionExpression(
                       "FILTER",
                       new MdxExpression[]
            {
                drillDownExpr,

                new MdxBinaryExpression(
                    new MdxBinaryExpression(

                        new MdxBinaryExpression
                        (
                            // ПЕРВОЕ УСЛОВИЕ - Убираем сам элемент если у него количество дочерних не равно 0
                            new MdxUnaryExpression
                            (
                                "not ",
                                new MdxBinaryExpression
                                (
                                    // Левый операнд
                                    // Кусок([Номенклатура].[Вид-Группа-Номенклатура].CURRENTMEMBER is [Номенклатура].[Вид-Группа-Номенклатура].[Номенклатура].&[0x80000000000000DE])
                                    new MdxBinaryExpression(
                                        new MdxPropertyExpression(
                                            new MdxObjectReferenceExpression(context.HierarchyUniqueName),
                                            "CURRENTMEMBER")
                                        ,
                                        new MdxObjectReferenceExpression(context.MemberUniqueName),
                                        " is "
                                        ),
                                    // Правый операнд
                                    // Кусок ([Номенклатура].[Вид-Группа-Номенклатура].[Номенклатура].&[0x80000000000000DE].Children.Count <> 0)
                                    new MdxBinaryExpression(
                                        // Левый операнд
                                        new MdxPropertyExpression(
                                            new MdxPropertyExpression(
                                                new MdxObjectReferenceExpression(context.MemberUniqueName),
                                                "Children"),
                                            "Count"),
                                        // Правый операнд
                                        new MdxConstantExpression("0", MdxConstantKind.Integer),
                                        // Операция
                                        "<>"
                                        ),
                                    // Операция
                                    "AND"
                                )

                            ),
                            // ВТОРОЕ УСЛОВИЕ - Убираем соседей, кроме самого элемента
                            new MdxUnaryExpression
                            (
                                "not ",
                                new MdxBinaryExpression
                                (
                                    // Левый операнд
                                    // Кусок IsSibling([Номенклатура].[Вид-Группа-Номенклатура].CURRENTMEMBER,[Номенклатура].[Вид-Группа-Номенклатура].[Номенклатура].&[0x80000000000000DE])
                                    new MdxFunctionExpression
                                    (
                                        "IsSibling",
                                        new MdxExpression[]
                {
                    new MdxPropertyExpression(
                        new MdxObjectReferenceExpression(context.HierarchyUniqueName),
                        "CURRENTMEMBER"),
                    new MdxObjectReferenceExpression(context.MemberUniqueName)
                }
                                    ),
                                    // Правый операнд
                                    // Кусок not([Номенклатура].[Вид-Группа-Номенклатура].CURRENTMEMBER is [Номенклатура].[Вид-Группа-Номенклатура].[Номенклатура].&[0x80000000000000DE])
                                    new MdxUnaryExpression
                                    (
                                        "not ",
                                        new MdxBinaryExpression
                                        (
                                            new MdxPropertyExpression(
                                                new MdxObjectReferenceExpression(context.HierarchyUniqueName),
                                                "CURRENTMEMBER")
                                            ,
                                            new MdxObjectReferenceExpression(context.MemberUniqueName),
                                            " is "
                                        )
                                    )
                                    ,
                                    // Операция
                                    "AND"
                                )
                            )
                            ,
                            // Операция
                            "AND"
                        ),
                        // ТРЕТЬЕ УСЛОВИЕ - Убираем предков элемента
                        new MdxUnaryExpression
                        (
                            "not ",
                            new MdxFunctionExpression(
                                "IsAncestor",
                                new MdxExpression[]
                {
                    new MdxPropertyExpression(
                        new MdxObjectReferenceExpression(context.HierarchyUniqueName),
                        "CURRENTMEMBER"),
                    new MdxObjectReferenceExpression(context.MemberUniqueName)
                })
                        )
                        ,
                        // Операция
                        "AND"
                        )
                    ,

                    // ЧЕТВЕРТОЕ УСЛОВИЕ - Оставляем только потомков
                    // Кусок IsAncestor([Номенклатура].[Вид-Группа-Номенклатура].[Номенклатура].&[0x80000000000000DE], [Номенклатура].[Вид-Группа-Номенклатура].CURRENTMEMBER) or ([Номенклатура].[Вид-Группа-Номенклатура].CURRENTMEMBER is [Номенклатура].[Вид-Группа-Номенклатура].[Номенклатура].&[0x80000000000000DE])
                    new MdxBinaryExpression
                    (
                        new MdxFunctionExpression
                        (
                            "IsAncestor",
                            new MdxExpression[]
                {
                    new MdxObjectReferenceExpression(context.MemberUniqueName),
                    new MdxPropertyExpression(
                        new MdxObjectReferenceExpression(context.HierarchyUniqueName),
                        "CURRENTMEMBER")
                }
                        ),
                        new MdxBinaryExpression
                        (
                            new MdxPropertyExpression(
                                new MdxObjectReferenceExpression(context.HierarchyUniqueName),
                                "CURRENTMEMBER")
                            ,
                            new MdxObjectReferenceExpression(context.MemberUniqueName),
                            " is "
                        ),
                        "OR"
                    )
                    ,
                    // Операция
                    "AND"
                    )
            }
                       ));
        }
 protected abstract MdxObject ProcessCore(MdxObject mdx, MdxActionContext context);
 public MdxObject Process(MdxObject mdx, MdxActionContext context)
 {
     return(this.ProcessCore(mdx, context));
 }