public static bool IsAtOrAboveGranularity(DimensionAttribute attribute, MeasureGroupDimension mgDim)
 {
     if (mgDim is RegularMeasureGroupDimension)
     {
         MeasureGroupAttribute granularity = GetGranularityAttribute((RegularMeasureGroupDimension)mgDim);
         if (granularity.AttributeID == attribute.ID)
         {
             return(true);
         }
         return(IsParentOf(attribute, granularity.Attribute));
     }
     else if (mgDim is ManyToManyMeasureGroupDimension)
     {
         //this depends on the granularity of the m2m dimension as it appears on the intermediate measure group
         ManyToManyMeasureGroupDimension m2mDim = (ManyToManyMeasureGroupDimension)mgDim;
         return(IsAtOrAboveGranularity(attribute, m2mDim.MeasureGroup.Dimensions.Find(mgDim.CubeDimensionID)));
     }
     else
     {
         return(true);
     }
 }
Пример #2
0
        /// <summary>
        /// Add reference dim usage
        /// </summary>
        /// <param name="measureGroup"></param>
        /// <param name="referenceDimID"></param>
        /// <param name="referenceDimAttrID"></param>
        /// <param name="interDimID"></param>
        /// <param name="interDimAttrID"></param>
        internal static void ADD_DIM_USAGE_REFERENCE_RELATIONSHIP(
            MeasureGroup measureGroup,
            String referenceDimID,
            String referenceDimAttrID,
            String interDimID,
            String interDimAttrID)
        {
            MeasureGroupDimension regDim = measureGroup.Dimensions.Find(referenceDimID);

            if (regDim != null)
            {
                measureGroup.Dimensions.Remove(regDim);
            }
            ReferenceMeasureGroupDimension regMgDim = new ReferenceMeasureGroupDimension();

            regMgDim.CubeDimensionID             = referenceDimID;
            regMgDim.IntermediateCubeDimensionID = interDimID;
            MeasureGroupAttribute mgAttr = regMgDim.Attributes.Add(referenceDimAttrID);

            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            regMgDim.IntermediateGranularityAttributeID = interDimAttrID;
            regMgDim.Materialization = ReferenceDimensionMaterialization.Regular;
            measureGroup.Dimensions.Add(regMgDim);
        }
Пример #3
0
        /// <summary>
        /// Recursive function. Adds nodes to the tree view control.
        /// Adds nodes accourding to attribute relationships
        /// </summary>

        private void AddTreeViewNodeChildren(TreeNode node, CubeAttribute cubeDimAttr , MeasureGroupDimension mgDim)
        {
            bool bIsAtOrAboveGranularity = ValidateAggs.IsAtOrAboveGranularity(cubeDimAttr.Attribute, mgDim);
            if (!bIsAtOrAboveGranularity)
            {
                node.ForeColor = belowGranularityColor;
            }
            else if (mgDim is ReferenceMeasureGroupDimension)
            {
                ReferenceMeasureGroupDimension refDim = (ReferenceMeasureGroupDimension)mgDim;
                if (refDim.Materialization == ReferenceDimensionMaterialization.Indirect)
                {
                    node.ForeColor = nonMaterializedColor;
                }
            }
            else if (cubeDimAttr.Attribute.Usage == AttributeUsage.Parent)
            {
                node.ForeColor = parentChildAttributeColor;
            }

            foreach (AttributeRelationship attRel in cubeDimAttr.Attribute.AttributeRelationships)
            {
                CubeAttribute childAttr = cubeDimAttr.Parent.Attributes.Find(attRel.AttributeID);
                if (childAttr == null) break; 
                TreeNode childNode = node.Nodes.Add(childAttr.AttributeID, childAttr.Attribute.Name);
                if (!childAttr.AttributeHierarchyEnabled)
                {
                    childNode.NodeFont = new Font(treeViewAggregation.Font, FontStyle.Italic);
                    childNode.ForeColor = Color.Gray;
                }

                childNode.Tag = attRel;
                AddTreeViewNodeChildren( childNode, childAttr,mgDim);
            }
        }
 private static ColumnBinding GetReferenceDimensionIntermediateAttributeColumn(MeasureGroupDimension mgdim)
 {
     if (mgdim is ReferenceMeasureGroupDimension)
     {
         ReferenceMeasureGroupDimension refmgdim = (ReferenceMeasureGroupDimension)mgdim;
         if (refmgdim.IntermediateGranularityAttribute.Attribute.KeyColumns.Count != 1)
         {
             throw new Exception("Reference dimension " + refmgdim.CubeDimension.Name + " had intermediate attribute with a composite key and this isn't supported by CreatePartitions.");
         }
         return GetColumnBindingForDataItem(refmgdim.IntermediateGranularityAttribute.Attribute.KeyColumns[0]);
     }
     return null;
 }
 internal static MeasureGroupAttribute GetGranularityAttribute(MeasureGroupDimension mgdim)
 {
     if (mgdim is ReferenceMeasureGroupDimension)
     {
         ReferenceMeasureGroupDimension refmgdim = (ReferenceMeasureGroupDimension)mgdim;
         foreach (MeasureGroupAttribute a in ((RegularMeasureGroupDimension)refmgdim.Parent.Dimensions[refmgdim.IntermediateCubeDimensionID]).Attributes)
         {
             if (a.Type == MeasureGroupAttributeType.Granularity)
                 return a;
         }
         throw new Exception("Granularity attribute not found in reference measure group dimension " + mgdim.CubeDimension.Name);
     }
     else if (mgdim is RegularMeasureGroupDimension)
     {
         foreach (MeasureGroupAttribute a in ((RegularMeasureGroupDimension)mgdim).Attributes)
         {
             if (a.Type == MeasureGroupAttributeType.Granularity)
                 return a;
         }
         throw new Exception("Granularity attribute not found in measure group dimension " + mgdim.CubeDimension.Name);
     }
     else
     {
         throw new Exception("Only measure group dimensions which are regular or reference are supported. " + mgdim.CubeDimension.Name + " is type " + mgdim.GetType().Name);
     }
 }
Пример #6
0
 public static bool IsAtOrAboveGranularity(DimensionAttribute attribute, MeasureGroupDimension mgDim)
 {
     if (mgDim is RegularMeasureGroupDimension)
     {
         MeasureGroupAttribute granularity = GetGranularityAttribute((RegularMeasureGroupDimension)mgDim);
         if (granularity.AttributeID == attribute.ID)
             return true;
         return IsParentOf(attribute, granularity.Attribute);
     }
     else if (mgDim is ManyToManyMeasureGroupDimension)
     {
         //this depends on the granularity of the m2m dimension as it appears on the intermediate measure group
         ManyToManyMeasureGroupDimension m2mDim = (ManyToManyMeasureGroupDimension)mgDim;
         return IsAtOrAboveGranularity(attribute, m2mDim.MeasureGroup.Dimensions.Find(mgDim.CubeDimensionID));
     }
     else
     {
         return true;
     }
 }
        private static List <AggValidationWarning> CheckAggDesign(AggregationDesign aggDesign, string sCorrectAggregationDesignName, string sReportTitle)
        {
            List <AggValidationWarning> masterWarnings = new List <AggValidationWarning>();

            //check for m2m agg problems
            foreach (Aggregation agg in aggDesign.Aggregations)
            {
                foreach (AggregationDimension aggDim in agg.Dimensions)
                {
                    if (aggDim.Attributes.Count > 0 && aggDim.MeasureGroupDimension is ManyToManyMeasureGroupDimension)
                    {
                        ManyToManyMeasureGroupDimension m2mDim = (ManyToManyMeasureGroupDimension)aggDim.MeasureGroupDimension;
                        MeasureGroup intermediateMG            = m2mDim.MeasureGroup;
                        List <MeasureGroupAttribute> missing   = new List <MeasureGroupAttribute>();
                        foreach (MeasureGroupDimension commonDim in intermediateMG.Dimensions)
                        {
                            RegularMeasureGroupDimension regCommonDim = commonDim as RegularMeasureGroupDimension;
                            if (commonDim.CubeDimensionID != aggDim.CubeDimensionID || regCommonDim == null)
                            {
                                if (!aggDim.ParentMeasureGroup.Dimensions.Contains(commonDim.CubeDimensionID))
                                {
                                    continue;                                                                            //this isn't a shared dimension
                                }
                                MeasureGroupDimension dataMeasureGroupDim = aggDim.ParentMeasureGroup.Dimensions[commonDim.CubeDimensionID];
                                if (dataMeasureGroupDim is ManyToManyMeasureGroupDimension)
                                {
                                    continue;                                                         //this shared dimension is m2m on the data measure group so don't include it
                                }
                                //this is a common dimension and the granularity attribute on the intermediate measure group needs to be in the agg
                                bool bFoundGranularityAgg          = false;
                                MeasureGroupAttribute mga          = GetGranularityAttribute(regCommonDim);
                                AggregationDimension  aggCommonDim = agg.Dimensions.Find(commonDim.CubeDimensionID);
                                if (aggCommonDim != null)
                                {
                                    if (aggCommonDim.Attributes.Find(mga.AttributeID) != null)
                                    {
                                        bFoundGranularityAgg = true;
                                    }
                                }
                                if (!bFoundGranularityAgg && mga != null)
                                {
                                    missing.Add(mga);
                                }
                            }
                        }
                        string sWarning = "This aggregation contains many-to-many dimension [" + m2mDim.CubeDimension.Name + "]. It will not be used unless it also contains ";
                        for (int i = 0; i < missing.Count; i++)
                        {
                            MeasureGroupAttribute mga = missing[i];
                            if (i > 0)
                            {
                                sWarning += " and ";
                            }
                            sWarning += "[" + mga.Parent.CubeDimension.Name + "].[" + mga.Attribute.Name + "]";
                        }

                        if (missing.Count == 0)
                        {
                            sWarning = "";
                        }
                        else
                        {
                            sWarning += ". ";
                        }
                        sWarning += "The many-to-many dimension [" + m2mDim.CubeDimension.Name + "] itself should not be included in the aggregation to workaround a bug.";

                        masterWarnings.Add(new AggValidationWarning(agg, sCorrectAggregationDesignName, sWarning, sReportTitle));
                    }
                }
            }

            //check for non-materialized reference dimensions
            foreach (Aggregation agg in aggDesign.Aggregations)
            {
                foreach (AggregationDimension aggDim in agg.Dimensions)
                {
                    if (aggDim.Attributes.Count > 0 && aggDim.MeasureGroupDimension is ReferenceMeasureGroupDimension)
                    {
                        ReferenceMeasureGroupDimension refDim = (ReferenceMeasureGroupDimension)aggDim.MeasureGroupDimension;
                        if (refDim.Materialization == ReferenceDimensionMaterialization.Indirect)
                        {
                            string sWarning = "This aggregation contains a non-materialized reference dimension [" + refDim.CubeDimension.Name + "] which is not supported.";
                            masterWarnings.Add(new AggValidationWarning(agg, sCorrectAggregationDesignName, sWarning, sReportTitle));
                        }
                    }
                }
            }

            //check whether all measures are semi-additive
            bool bAllMeasuresAreSemiAdditive = true;

            foreach (Measure m in aggDesign.Parent.Measures)
            {
                if (m.AggregateFunction == AggregationFunction.Count || m.AggregateFunction == AggregationFunction.DistinctCount || m.AggregateFunction == AggregationFunction.Sum || m.AggregateFunction == AggregationFunction.Min || m.AggregateFunction == AggregationFunction.Max || m.AggregateFunction == AggregationFunction.None)
                {
                    bAllMeasuresAreSemiAdditive = false;
                    break;
                }
                else if (m.AggregateFunction == AggregationFunction.ByAccount)
                {
                    //if it's a ByAccount measure, we need to check the list of AggregationFunctions on each account
                    foreach (Account acct in aggDesign.ParentDatabase.Accounts)
                    {
                        if (acct.AggregationFunction == AggregationFunction.Sum) //Sum is the only additive AggregationFunction allowed in account intelligence
                        {
                            bAllMeasuresAreSemiAdditive = false;
                            break;
                        }
                    }
                }
            }

            //if all measures are semi-additive, find the Time dimension the semi-additive behavior operates on (which we think is the first Time dimension)
            if (bAllMeasuresAreSemiAdditive)
            {
                CubeDimension         semiAdditiveDim   = null;
                MeasureGroupDimension semiAdditiveMgDim = null;
                foreach (CubeDimension cd in aggDesign.ParentCube.Dimensions)
                {
                    MeasureGroupDimension mgd = aggDesign.Parent.Dimensions.Find(cd.ID);
                    if (mgd != null && mgd.Dimension.Type == DimensionType.Time)
                    {
                        semiAdditiveDim   = mgd.CubeDimension;
                        semiAdditiveMgDim = mgd;
                        break;
                    }
                }

                if (semiAdditiveDim == null || semiAdditiveMgDim == null || !(semiAdditiveMgDim is RegularMeasureGroupDimension))
                {
                    //TODO: should we warn about this?
                }
                else
                {
                    foreach (Aggregation agg in aggDesign.Aggregations)
                    {
                        AggregationDimension  semiAdditiveAggDim = agg.Dimensions.Find(semiAdditiveDim.ID);
                        MeasureGroupAttribute granularity        = GetGranularityAttribute((RegularMeasureGroupDimension)semiAdditiveMgDim);
                        if (semiAdditiveAggDim == null || semiAdditiveAggDim.Attributes.Find(granularity.AttributeID) == null)
                        {
                            string sWarning = "This measure group contains only semi-additive measures. This aggregation will not be used when semi-additive measure values are retrieved because it does not include the granularity attribute of the semi-additive dimension ([" + semiAdditiveDim.Name + "].[" + granularity.Attribute.Name + "]). (The Exists-with-a-measure-group function can still run off this aggregation, though.)";
                            masterWarnings.Add(new AggValidationWarning(agg, sCorrectAggregationDesignName, sWarning, sReportTitle));
                        }
                    }
                }
            }

            //check for aggs on parent-child attributes
            foreach (Aggregation agg in aggDesign.Aggregations)
            {
                foreach (AggregationDimension aggDim in agg.Dimensions)
                {
                    foreach (AggregationAttribute attr in aggDim.Attributes)
                    {
                        if (attr.Attribute.Usage == AttributeUsage.Parent)
                        {
                            string sWarning = "This aggregation contains [" + aggDim.CubeDimension.Name + "].[" + attr.Attribute.Name + "] which is a parent-child attribute. This is not allowed. The aggregation should include [" + aggDim.CubeDimension.Name + "].[" + aggDim.Dimension.KeyAttribute.Name + "] instead.";
                            masterWarnings.Add(new AggValidationWarning(agg, sCorrectAggregationDesignName, sWarning, sReportTitle));
                        }
                    }
                }
            }

            //check for aggs on AttributeHierarchyEnabled=false attributes
            foreach (Aggregation agg in aggDesign.Aggregations)
            {
                foreach (AggregationDimension aggDim in agg.Dimensions)
                {
                    foreach (AggregationAttribute attr in aggDim.Attributes)
                    {
                        if (!attr.CubeAttribute.AttributeHierarchyEnabled)
                        {
                            string sWarning = "This aggregation contains [" + aggDim.CubeDimension.Name + "].[" + attr.Attribute.Name + "] which is not enabled as an attribute hierarchy. This is not allowed.";
                            masterWarnings.Add(new AggValidationWarning(agg, sCorrectAggregationDesignName, sWarning, sReportTitle));
                        }
                    }
                }
            }

            //find a list of ALTER statements that alter the DEFAULT_MEMBER property in the calc script
            List <string> attributesWithDefaultMemberAlteredInCalcScript = new List <string>();

            System.Text.RegularExpressions.Regex regEx = new System.Text.RegularExpressions.Regex(@"ALTER\s+CUBE\s+(CURRENTCUBE|\[?" + aggDesign.ParentCube.Name + @"\]?)\s+UPDATE\s+DIMENSION\s+(.+?)\s*\,\s*DEFAULT_MEMBER\s+", System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Multiline);
            foreach (MdxScript script in aggDesign.ParentCube.MdxScripts)
            {
                if (script.DefaultScript)
                {
                    StringBuilder sCommands = new StringBuilder();
                    foreach (Command cmd in script.Commands)
                    {
                        sCommands.AppendLine(cmd.Text);
                    }
                    foreach (System.Text.RegularExpressions.Match match in regEx.Matches(sCommands.ToString()))
                    {
                        try
                        {
                            attributesWithDefaultMemberAlteredInCalcScript.Add(match.Groups[2].Captures[0].Value.ToLower());
                        }
                        catch { }
                    }
                    break;
                }
            }

            //build list of cube dimension attributes that have default members, are not aggregatable, or are marked as AggregationUsage=Full
            foreach (MeasureGroupDimension mgDim in aggDesign.Parent.Dimensions)
            {
                if (mgDim is ManyToManyMeasureGroupDimension)
                {
                    continue;                                           //don't suggest adding any m2m dimensions
                }
                CubeDimension cd = mgDim.CubeDimension;
                foreach (CubeAttribute ca in cd.Attributes)
                {
                    if (!ca.AttributeHierarchyEnabled)
                    {
                        continue;
                    }
                    if (!IsAtOrAboveGranularity(ca.Attribute, mgDim))
                    {
                        continue;
                    }

                    foreach (Aggregation agg in aggDesign.Aggregations)
                    {
                        AggregationDimension aggDim = agg.Dimensions.Find(cd.ID);
                        if (ca.Attribute.Usage == AttributeUsage.Parent)
                        {
                            if (!(mgDim is RegularMeasureGroupDimension))
                            {
                                continue;
                            }
                            if (!IsAtOrAboveGranularity(cd.Dimension.KeyAttribute, mgDim))
                            {
                                continue;
                            }

                            //if this is a parent-child attribute and the key isn't in the agg, then check whether the parent-child attribute has a DefaultMember or is aggregatable
                            if (aggDim == null || aggDim.Attributes.Find(cd.Dimension.KeyAttribute.ID) == null)
                            {
                                string sWarning = "";
                                if (!string.IsNullOrEmpty(ca.Attribute.DefaultMember) || attributesWithDefaultMemberAlteredInCalcScript.Contains(((string)("[" + cd.Name + "].[" + ca.Attribute.Name + "]")).ToLower()))
                                {
                                    sWarning += "has a DefaultMember";
                                }

                                if (!ca.Attribute.IsAggregatable)
                                {
                                    if (!string.IsNullOrEmpty(sWarning))
                                    {
                                        sWarning += " and ";
                                    }
                                    sWarning += "is not aggregatable";
                                }

                                if (!string.IsNullOrEmpty(sWarning))
                                {
                                    sWarning = "This aggregation should probably contain [" + cd.Name + "].[" + cd.Dimension.KeyAttribute.Name + "] because [" + cd.Name + "].[" + ca.Attribute.Name + "] is a parent-child attribute which " + sWarning + ".";
                                    masterWarnings.Add(new AggValidationWarning(agg, sCorrectAggregationDesignName, sWarning, sReportTitle));
                                }
                            }
                        }
                        //for non-parent-child attributes...
                        else if (aggDim == null || aggDim.Attributes.Find(ca.AttributeID) == null)
                        {
                            string sWarning = "";
                            if (!string.IsNullOrEmpty(ca.Attribute.DefaultMember) || attributesWithDefaultMemberAlteredInCalcScript.Contains(((string)("[" + cd.Name + "].[" + ca.Attribute.Name + "]")).ToLower()))
                            {
                                sWarning += "has a DefaultMember";
                            }

                            if (!ca.Attribute.IsAggregatable)
                            {
                                if (!string.IsNullOrEmpty(sWarning))
                                {
                                    sWarning += " and ";
                                }
                                sWarning += "is not aggregatable";
                            }

                            if (ca.AggregationUsage == AggregationUsage.Full)
                            {
                                if (!string.IsNullOrEmpty(sWarning))
                                {
                                    sWarning += " and ";
                                }
                                sWarning += "is marked as AggregationUsage=Full";
                            }

                            if (aggDim != null && AggContainsChild(aggDim, ca.Attribute))
                            {
                                continue;                                                           //if this attribute is redundant, then no need to warn about it
                            }
                            if (!string.IsNullOrEmpty(sWarning))
                            {
                                sWarning = "This aggregation should probably contain [" + cd.Name + "].[" + ca.Attribute.Name + "] which " + sWarning + ".";
                                masterWarnings.Add(new AggValidationWarning(agg, sCorrectAggregationDesignName, sWarning, sReportTitle));
                            }
                        }
                    }
                }
            }

            //look for aggs with redundant attributes
            foreach (Aggregation agg in aggDesign.Aggregations)
            {
                bool bHasRedundancy = false;
                foreach (AggregationDimension aggDim in agg.Dimensions)
                {
                    foreach (AggregationAttribute attr in aggDim.Attributes)
                    {
                        if (AggContainsParent(aggDim, attr.Attribute))
                        {
                            bHasRedundancy = true;
                            break;
                        }
                    }
                    if (bHasRedundancy)
                    {
                        break;
                    }
                }
                if (bHasRedundancy)
                {
                    string sWarning = "This aggregation contains redundant attributes which unnecessarily bloat the size of the aggregation.";
                    masterWarnings.Add(new AggValidationWarning(agg, sCorrectAggregationDesignName, sWarning, sReportTitle));
                }
            }

            //check for aggs on below granularity attributes
            foreach (Aggregation agg in aggDesign.Aggregations)
            {
                foreach (AggregationDimension aggDim in agg.Dimensions)
                {
                    foreach (AggregationAttribute attr in aggDim.Attributes)
                    {
                        if (!IsAtOrAboveGranularity(attr.Attribute, aggDim.MeasureGroupDimension))
                        {
                            string sWarning = "This aggregation contains [" + aggDim.CubeDimension.Name + "].[" + attr.Attribute.Name + "] which is below granularity. This is not allowed.";
                            masterWarnings.Add(new AggValidationWarning(agg, sCorrectAggregationDesignName, sWarning, sReportTitle));
                        }
                    }
                }
            }

            return(masterWarnings);
        }
Пример #8
0
        static void PartitionInfo()
        {
            string srv_name  = @"SCRBMSBDK000660";
            string db_name   = "FBR_FYPnL_DPRD";
            string cube_name = "FYPnL Cube";
            string mg_name   = "USD";

            //TextWriter tw = new StreamWriter("date.txt", true);

            Microsoft.AnalysisServices.Server   srv;
            Microsoft.AnalysisServices.Database db;

            srv = new Microsoft.AnalysisServices.Server();
            try
            {
                srv.Connect(srv_name);
                logMessageFmt("Databases on [{0}]: {1}", srv_name, srv.Databases.Count);

                db = srv.Databases.FindByName(db_name);

                Cube cube = db.Cubes.FindByName(cube_name);

                CubeDimension      cubedim = cube.Dimensions[0];
                Dimension          dbdim   = cubedim.Dimension;
                DimensionAttribute dbattr  = dbdim.Attributes[0];

                //var Source = dbattr.Source;
                System.Data.DataSet ds = dbdim.DataSourceView.Schema;
                string    dsid         = db.DataSourceViews[0].DataSourceID;
                DataTable dt           = db.DataSourceViews[0].Schema.Tables[0];
                //db.DataSources[0].
                //DataTable dt = ds.Tables["SHARED_DimBrand"];
                //ep = dt.ExtendedProperties.

                MeasureGroup                 mg    = cube.MeasureGroups.FindByName(mg_name);
                MeasureGroupDimension        mgd   = mg.Dimensions[0];
                List <MeasureGroupAttribute> alist = new List <MeasureGroupAttribute>();

                if (mgd is RegularMeasureGroupDimension)
                {
                    RegularMeasureGroupDimension rmgd = (RegularMeasureGroupDimension)mgd;
                    foreach (MeasureGroupAttribute mgattr in rmgd.Attributes)
                    {
                        if (mgattr.Type == MeasureGroupAttributeType.Granularity)
                        {
                            alist.Add(mgattr);
                        }
                    }
                    //MeasureGroupAttribute mgattr = rmgd.Attributes.f["Key"];
                }
                Type t = alist[0].KeyColumns[0].Source.GetType();

                Measure msr = mg.Measures[0];

                foreach (Partition part in mg.Partitions)
                {
                    string         src;
                    TabularBinding tb = part.Source;
                    if (tb is QueryBinding)
                    {
                        src = String.Format("QUERY: {0}", ((QueryBinding)tb).QueryDefinition);
                    }
                    else if (tb is TableBinding)
                    {
                        src = String.Format("TABLE: {0}.{1}", ((TableBinding)tb).DbSchemaName, ((TableBinding)tb).DbTableName);
                    }
                    else if (tb is DsvTableBinding)
                    {
                        src = String.Format("DSV: {0}.{1}", ((DsvTableBinding)tb).DataSourceViewID, ((DsvTableBinding)tb).TableID);
                    }
                    else
                    {
                        src = String.Empty;
                    }

                    logMessageFmt("Partition [{0}]: {1}", part.Name, src /*part.EstimatedRows*/);
                    //part.Process()
                }
                //Partition part = mg.Partitions[0]; //.FindByName(part_name);

                logMessage("Done.");
                Console.ReadKey();
            }
            finally
            {
                if (srv.Connected == true)
                {
                    srv.Disconnect();
                }
            }
        }
        // Compare if attributeA is included in AttributeB
        private static Boolean IsRedundantAttribute(MeasureGroup mg1, string DimId, string AttributeA, string AttributeB, Boolean CompareEstimatedCount, long OriginalEstimatedCount)
        {
            if (mg1 == null)
            {
                return(false);
            }

            long  lngMembersDelta;
            float flDeltaRatio;
            float flPonderatedDeltaRatio;
            long  lngEstimatedCountToSendRecursively;

            MeasureGroupDimension dimension = mg1.Dimensions.Find(DimId);

            if (dimension == null)
            {
                return(false);
            }

            CubeAttribute cubeattribute = dimension.CubeDimension.Attributes.Find(AttributeB);

            if (cubeattribute == null)
            {
                return(false);
            }

            // Check if AttributeA is included in AttributeB by
            // standing on AttributeB and recursively searching for AttributeA in all its child relationships
            foreach (AttributeRelationship attrRel in cubeattribute.Attribute.AttributeRelationships)
            {
                CubeAttribute childAttr = cubeattribute.Parent.Attributes.Find(attrRel.AttributeID);
                if (attrRel.AttributeID == AttributeA)
                {
                    // if CompareEstimatedCount is turn off, attribute is definitely included
                    if (!CompareEstimatedCount)
                    {
                        return(true);
                    }
                    else
                    {
                        // Else calculate the delta between Estimated Counts
                        if (OriginalEstimatedCount > 0)
                        {
                            lngMembersDelta = (OriginalEstimatedCount - childAttr.Attribute.EstimatedCount);
                        }
                        else
                        {
                            lngMembersDelta = (cubeattribute.Attribute.EstimatedCount - childAttr.Attribute.EstimatedCount);
                        }
                        // Calculate the ratio between the delta and the child estimated count.
                        flDeltaRatio = (float)lngMembersDelta / (float)childAttr.Attribute.EstimatedCount;
                        // Ponderate delta ratio by multiplying it by intMembersDelta
                        flPonderatedDeltaRatio = flDeltaRatio * (float)lngMembersDelta;
                        // Testings on different scenarios demostrated that if flPonderatedDeltaRatio > 1000 both attributes have much different cardinality.
                        if (flPonderatedDeltaRatio < 1000)
                        {
                            // if AttributeA is included in AttributeB and besides their cardinality are similar
                            // then A is definitely included in B.
                            return(true);
                        }
                    }
                }
                if (childAttr.Attribute.AttributeRelationships.Count > 0)
                {
                    // If in first iteration, OriginalEstimatedCount is null and base Estimated Count es get from AttributeB
                    // if second or later iteration, it pushes the OriginalEstimatedCount
                    if (OriginalEstimatedCount == -1)
                    {
                        lngEstimatedCountToSendRecursively = cubeattribute.Attribute.EstimatedCount;
                    }
                    else
                    {
                        lngEstimatedCountToSendRecursively = OriginalEstimatedCount;
                    }

                    if (IsRedundantAttribute(mg1, DimId, AttributeA, childAttr.AttributeID, CompareEstimatedCount, lngEstimatedCountToSendRecursively))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }