private static List <AggDimension> ListAggDimensions(AggregationDesign aggDesign, string sCorrectAggregationDesignName, string sReportTitle)
        {
            int iHighlight           = 0;
            List <AggDimension> aggs = new List <AggDimension>();

            foreach (Aggregation agg in aggDesign.Aggregations)
            {
                iHighlight++;
                foreach (MeasureGroupDimension mgd in agg.ParentMeasureGroup.Dimensions)
                {
                    AggregationDimension ad = agg.Dimensions.Find(mgd.CubeDimensionID);
                    if (ad == null)
                    {
                        try
                        {
                            ad = agg.Dimensions.Add(mgd.CubeDimensionID);
                            aggs.Add(new AggDimension(ad, sCorrectAggregationDesignName, sReportTitle, (iHighlight % 2 == 0)));
                        }
                        finally
                        {
                            try
                            {
                                agg.Dimensions.Remove(ad);
                            }
                            catch { }
                        }
                    }
                    else
                    {
                        aggs.Add(new AggDimension(ad, sCorrectAggregationDesignName, sReportTitle, (iHighlight % 2 == 0)));
                    }
                }
            }
            return(aggs);
        }
 private static bool AggContainsChild(AggregationDimension aggDim, DimensionAttribute attr)
 {
     foreach (AggregationAttribute aggAttr in aggDim.Attributes)
     {
         if (IsParentOf(attr, aggAttr.Attribute))
         {
             return(true);
         }
     }
     return(false);
 }
 private static bool AggContainsParent(AggregationDimension aggDim, DimensionAttribute attr)
 {
     foreach (AttributeRelationship rel in attr.AttributeRelationships)
     {
         if (aggDim.Attributes.Find(rel.AttributeID) != null)
         {
             return(true);
         }
         else if (AggContainsParent(aggDim, rel.Attribute))
         {
             return(true);
         }
     }
     return(false);
 }
Exemple #4
0
        public void ITable_Distinct(Func <ITable> factoryMethod)
        {
            // Define columns and add sample data
            ITable table = factoryMethod();

            AddSampleData(table);

            // Get Distinct Priority for all bugs, verify three (0, 1, 3)
            DistinctQuery  query  = new DistinctQuery("Priority", "", 5);
            DistinctResult result = table.Query(query);

            // sort the results because order is not garenteed by distinct query
            Array values = result.Values.GetColumn(0);

            Array.Sort(values);

            Assert.AreEqual("0, 1, 3", values.Join(", "));
            Assert.IsTrue(result.AllValuesReturned);

            // Verify the result converts to a dimension properly
            AggregationDimension dimension = result.ToAggregationDimension();

            Assert.AreEqual("Query [[Priority] = 0,[Priority] = 1,[Priority] = 3]", dimension.ToString());

            // Verify distinct priority where priority is not 1 has only two values
            query.Where = QueryParser.Parse("Priority != 1");
            result      = table.Query(query);

            // sort the results because order is not garenteed by distinct query
            values = result.Values.GetColumn(0);
            Array.Sort(values);

            Assert.AreEqual("0, 3", result.Values.GetColumn(0).Join(", "));
            Assert.IsTrue(result.AllValuesReturned);

            // Verify if we only ask for one value, query reports more values left
            query.Count = 1;
            result      = table.Query(query);

            // either value could come back, it's a race to whichever partition completes first
            Assert.IsTrue(
                ("0" == result.Values.GetColumn(0).Join(", ")) ||
                ("3" == result.Values.GetColumn(0).Join(", ")));

            Assert.IsFalse(result.AllValuesReturned);
        }
        /// <summary>
        /// Create aggregation design
        /// </summary>
        /// <param name="mg"></param>
        /// <param name="sqlHelper"></param>
        /// <param name="asMeta"></param>
        /// <returns></returns>
        public AggregationDesign CREATE_AGGREGATION_DESIGN(MeasureGroup mg, DB_SQLHELPER_BASE sqlHelper
                                                           , AS_METADATA asMeta)
        {
            DataTable         agg_design_list = null;
            AggregationDesign agg_design      = null;

            try
            {
                agg_design_list = asMeta.GET_SSAS_AGGREGATION_DESIGN_SET(sqlHelper, mg.ID);
                foreach (DataRow measure in agg_design_list.Rows)
                {
                    String AggregationDesignName = measure["aggregation_design_name"].ToString();
                    //agg_design=AggregationDesignName;

                    String AggregationName = measure["aggregation_name"].ToString();
                    String DimensionID     = measure["dimension_id"].ToString();
                    String AttributeID     = measure["attribute_id"].ToString();
                    if (mg.AggregationDesigns.Find(AggregationDesignName) == null)
                    {
                        mg.AggregationDesigns.Add(AggregationDesignName);
                    }

                    agg_design = mg.AggregationDesigns[AggregationDesignName];
                    Aggregation agg = agg_design.Aggregations.Find(AggregationName);
                    if (agg == null)
                    {
                        agg = agg_design.Aggregations.Add(AggregationName, AggregationName);
                    }
                    AggregationDimension agg_dim = agg.Dimensions.Find(DimensionID);
                    if (agg_dim == null)
                    {
                        agg.Dimensions.Add(DimensionID);
                    }
                    agg.Dimensions[DimensionID].Attributes.Add(AttributeID);
                }
            }
            catch (Exception ex)
            {
                sqlHelper.ADD_MESSAGE_LOG(ex.Message.ToString(), MESSAGE_TYPE.AGGREGATION_DESIGN, MESSAGE_RESULT_TYPE.Error);
                throw (ex);
            }
            return(agg_design);
        }
            public AggDimension(AggregationDimension aggDim, string sCorrectAggregationDesignName, string sReportTitle, bool bHighlightRow)
            {
                Aggregation agg = aggDim.Parent;

                mAggName               = agg.Name;
                mAggDesignName         = sCorrectAggregationDesignName;
                mMeasureGroupName      = agg.ParentMeasureGroup.Name;
                mCubeNameOrReportTitle = (sReportTitle == null ? agg.ParentCube.Name : sReportTitle);
                mDatabaseName          = agg.ParentDatabase.Name;
                mAttributes            = string.Empty;
                mDimension             = aggDim.CubeDimension.Name;
                mHighlightRow          = bHighlightRow;
                foreach (AggregationAttribute aa in aggDim.Attributes)
                {
                    if (!string.IsNullOrEmpty(mAttributes))
                    {
                        mAttributes += "\r\n";
                    }
                    mAttributes += aa.Attribute.Name;
                }
            }
        private static AggregationDimension RemoveRedundantAttributes(AggregationDimension dim)
        {
            AggregationDimension dimPurged = (AggregationDimension)dim.Clone();

            foreach (AggregationAttribute att1 in dimPurged.Attributes)
            {
                foreach (AggregationAttribute att2 in dimPurged.Attributes)
                {
                    if (att1.AttributeID == att2.AttributeID)
                    {
                        break;
                    }
                    if (IsRedundantAttribute(dimPurged.ParentMeasureGroup, dimPurged.CubeDimensionID, att1.AttributeID, att2.AttributeID, false, -1))
                    {
                        dimPurged.Attributes.Remove(att1);
                        break;
                    }
                }
            }
            return(dimPurged);
        }
Exemple #8
0
        public void ITable_DistinctTop(Func <ITable> factoryMethod)
        {
            // Define columns and add sample data
            ITable table = factoryMethod();

            AddSampleData(table);

            // Get Distinct Priority for all bugs, verify three (3, 0, 1)
            DistinctQueryTop query  = new DistinctQueryTop("Priority", "", 5);
            DistinctResult   result = table.Query(query);

            // Verify "3" is first, it's in 3 items, all values are returned, three distinct were returned
            Assert.AreEqual("3", result.Values[0, 0].ToString());
            Assert.AreEqual("3", result.Values[0, 1].ToString());
            Assert.AreEqual(3, result.Values.RowCount);
            Assert.AreEqual(5, result.Total);
            Assert.IsTrue(result.AllValuesReturned);

            // Verify distinct priority where priority is not 1 has only two values
            query.Where = QueryParser.Parse("Priority != 1");
            result      = table.Query(query);

            Assert.AreEqual("3, 0", result.Values.GetColumn(0).Join(", "));
            Assert.AreEqual(2, result.Values.RowCount);
            Assert.AreEqual(4, result.Total);
            Assert.IsTrue(result.AllValuesReturned);

            // Verify the result converts to a dimension properly
            AggregationDimension dimension = result.ToAggregationDimension();

            Assert.AreEqual("Query [[Priority] = 3,[Priority] = 0]", dimension.ToString());

            // Verify if we only ask for one value, query reports more values left
            query.Count = 1;
            result      = table.Query(query);
            Assert.AreEqual("3", result.Values[0, 0].ToString());
            Assert.AreEqual(1, result.Values.RowCount);
            Assert.IsFalse(result.AllValuesReturned);
        }
 public AggDimension(AggregationDimension aggDim, string sCorrectAggregationDesignName, string sReportTitle, bool bHighlightRow)
 {
     Aggregation agg = aggDim.Parent;
     mAggName = agg.Name;
     mAggDesignName = sCorrectAggregationDesignName;
     mMeasureGroupName = agg.ParentMeasureGroup.Name;
     mCubeNameOrReportTitle = (sReportTitle == null ? agg.ParentCube.Name : sReportTitle);
     mDatabaseName = agg.ParentDatabase.Name;
     mAttributes = string.Empty;
     mDimension = aggDim.CubeDimension.Name;
     mHighlightRow = bHighlightRow;
     foreach (AggregationAttribute aa in aggDim.Attributes)
     {
         if (!string.IsNullOrEmpty(mAttributes)) mAttributes += "\r\n";
         mAttributes += aa.Attribute.Name;
     }
 }
Exemple #10
0
        private static AggregationDimension RemoveRedundantAttributes(AggregationDimension dim)
        {
            AggregationDimension dimPurged = (AggregationDimension)dim.Clone();

            foreach (AggregationAttribute att1 in dimPurged.Attributes)
            {
                foreach (AggregationAttribute att2 in dimPurged.Attributes)
                {
                    if (att1.AttributeID == att2.AttributeID) break;
                    if (IsRedundantAttribute(dimPurged.ParentMeasureGroup, dimPurged.CubeDimensionID, att1.AttributeID, att2.AttributeID, false, -1))
                    {
                        dimPurged.Attributes.Remove(att1);
                        break;
                    }

                }
            }
            return dimPurged;
        }
Exemple #11
0
 private static bool AggContainsChild(AggregationDimension aggDim, DimensionAttribute attr)
 {
     foreach (AggregationAttribute aggAttr in aggDim.Attributes)
     {
         if (IsParentOf(attr, aggAttr.Attribute))
             return true;
     }
     return false;
 }
Exemple #12
0
 private static bool AggContainsParent(AggregationDimension aggDim, DimensionAttribute attr)
 {
     foreach (AttributeRelationship rel in attr.AttributeRelationships)
     {
         if (aggDim.Attributes.Find(rel.AttributeID) != null)
             return true;
         else if (AggContainsParent(aggDim, rel.Attribute))
             return true;
     }
     return false;
 }
        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);
        }
        internal static Boolean IsAggregationIncluded(Aggregation agg1, Aggregation agg2, Boolean bCountMembers)
        {
            Boolean bIsAttribute1Included = false;

            foreach (MeasureGroupDimension mgDim in agg1.ParentMeasureGroup.Dimensions)
            {
                AggregationDimension dim1 = agg1.Dimensions.Find(mgDim.CubeDimensionID);
                AggregationDimension dim2 = agg2.Dimensions.Find(mgDim.CubeDimensionID);

                if ((dim1 == null || dim1.Attributes.Count == 0) && (dim2 == null || dim2.Attributes.Count == 0))
                {
                    // both at the All level... continue
                    continue;
                }

                if ((dim1 != null && dim1.Attributes.Count > 0) && (dim2 == null || dim2.Attributes.Count == 0))
                {
                    // dim2 aggregates at All level so it's not possible it being more granular than dim1,
                    // then agg2 cannot contain agg1
                    return(false);
                }

                if ((dim1 == null || dim1.Attributes.Count == 0) && (dim2 != null && dim2.Attributes.Count > 0))
                {
                    // dim1 aggregates at All level so it's probable that all aggregation being included in dim2,
                    // but still have to evaluate the rest of attributes
                    continue;
                }

                if ((dim1 != null && dim1.Attributes.Count > 0) && (dim2 != null && dim2.Attributes.Count > 0))
                // both dim1 and dim2 have aggregations at lower level than All, so they need to be evaluated
                {
                    // For both Dim1 and Dim2 attributes, purge those attributes that are redundant
                    AggregationDimension dim1Purged = RemoveRedundantAttributes(dim1);
                    AggregationDimension dim2Purged = RemoveRedundantAttributes(dim2);


                    foreach (AggregationAttribute att1 in dim1Purged.Attributes)
                    {
                        if (dim2Purged.Attributes.Contains(att1.AttributeID))
                        {
                            continue;
                        }

                        Boolean bExistsAttributeInSameTree = false;
                        foreach (AggregationAttribute att2 in dim2Purged.Attributes)
                        {
                            bIsAttribute1Included = IsRedundantAttribute(agg1.ParentMeasureGroup, dim1.CubeDimensionID, att1.AttributeID, att2.AttributeID, false, -1);
                            //bIsAttribute2Included = IsRedundantAttribute(agg1.ParentMeasureGroup, dim1.CubeDimensionID, att2.AttributeID, att1.AttributeID, false, -1);

                            if (bIsAttribute1Included)
                            // Attribute att1 is included in att2, then if countmembers is turned on
                            // ponderated ratio will be calculated
                            // else go out for another attribute
                            {
                                if (bCountMembers)
                                {
                                    if (!IsRedundantAttribute(agg1.ParentMeasureGroup, dim1.CubeDimensionID, att1.AttributeID, att2.AttributeID, true, -1))
                                    {
                                        // If included but member count differ vastly, then report that agg1 is not included in agg2
                                        return(false);
                                    }
                                }
                                else
                                {
                                    bExistsAttributeInSameTree = true;
                                    break;
                                }
                            }
                        }
                        if (!bExistsAttributeInSameTree)
                        {
                            // if dim1 does not have attributes in same tree as dim2, then agg1 is not included.
                            return(false);
                        }
                    }
                }
            }

            // Finally if all dim1 are equal or included in dim2 then aggregation1 is included in aggregation2
            return(true);
        }