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); }
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); }
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; } }
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; }
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; }
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); }