public static IEnumerable <Flat> Flatten(CellSet cellSet) { var valueMeasures = new List <string>(); var axes = cellSet.Axes.Cast <Microsoft.AnalysisServices.AdomdClient.Axis>().ToList(); var members = new List <MemberPair>(); for (int i = 0; i < cellSet.Axes.Count; i++) { for (int j = 0; j < cellSet.Axes[i].Positions.Count; j++) { for (int k = 0; k < cellSet.Axes[i].Positions[j].Members.Count; k++) { var levelName = cellSet.Axes[i].Positions[j].Members[k].ParentLevel.Caption; if (levelName == "MeasuresLevel") { var name = cellSet.Axes[i].Positions[j].Members[i].Caption; if (!valueMeasures.Contains(name)) { valueMeasures.Add(name); } } else { var caption = cellSet.Axes[i].Positions[j].Members[k].Caption; members.Add(new MemberPair(levelName, caption)); } } } } var valueCount = valueMeasures.Count; var memberCount = members.Select(x => x.Level).Distinct().Count(); var totalLoops = valueCount == 0 ? 0 : cellSet.Cells.Count / valueCount; for (int i = 0; i < totalLoops; i++) { var flat = new Flat(); for (int j = 0; j < valueCount; j++) { flat.MeasureValues.Add(valueMeasures[j], cellSet[j + (i * valueCount)].Value); } for (int j = 0; j < memberCount; j++) { flat.PositionValues.Add(members[j].Level, members[j + (i * memberCount)].Member); } yield return(flat); } }
public static IEnumerable<Flat> Flatten(CellSet cellSet) { var valueMeasures = new List<string>(); var axes = cellSet.Axes.Cast<Microsoft.AnalysisServices.AdomdClient.Axis>().ToList(); var members = new List<MemberPair>(); for (int i = 0; i < cellSet.Axes.Count; i++) for(int j = 0; j < cellSet.Axes[i].Positions.Count; j++) for (int k = 0; k < cellSet.Axes[i].Positions[j].Members.Count; k++) { var levelName = cellSet.Axes[i].Positions[j].Members[k].ParentLevel.Caption; if (levelName == "MeasuresLevel") { var name = cellSet.Axes[i].Positions[j].Members[i].Caption; if(!valueMeasures.Contains(name)) valueMeasures.Add(name); } else { var caption = cellSet.Axes[i].Positions[j].Members[k].Caption; members.Add(new MemberPair(levelName, caption)); } } var valueCount = valueMeasures.Count; var memberCount = members.Select(x => x.Level).Distinct().Count(); var totalLoops = valueCount == 0 ? 0 : cellSet.Cells.Count / valueCount; for (int i = 0; i < totalLoops; i++) { var flat = new Flat(); for(int j = 0; j < valueCount; j++) { flat.MeasureValues.Add(valueMeasures[j], cellSet[j + (i * valueCount)].Value); } for(int j = 0; j < memberCount; j++) { flat.PositionValues.Add(members[j].Level, members[j + (i * memberCount)].Member); } yield return flat; } }
internal static IEnumerable <T> FlattenAndReturn <T>(this CellSet source) where T : new() { if (source.Axes.Count > 2) { var ex = new NotImplementedInPAS_Exception("Apologies, but maping to an object using more than two axes is not yet supported."); ex.ReasonWhy = "The differences in the Cell Values indexes have not been mapped yet."; throw ex; } var type = typeof(T); var flattend = Flat.Flatten(source); var names = flattend .SelectMany(x => x.MeasureValues.Select(y => y.Key).Distinct()) .Concat(flattend.SelectMany(x => x.PositionValues.Select(y => y.Key).Distinct())) .Distinct() .OrderBy(x => x); var arrayExp = Expression.Parameter(typeof(string[]), "values"); var converterArray = Expression.Parameter(typeof(TypeConverter[]), "converters"); var bindingList = new Dictionary <ParameterExpression, MemberAssignment>(); var ps = type.GetProperties() .Where(x => System.Attribute.IsDefined(x, typeof(MapToAttribute))) .Select(x => new { Attribute = x.GetCustomAttribute <MapToAttribute>(), PropertyInfo = x }) .Where(x => names.Contains(x.Attribute.MdxColumn)) .OrderBy(x => x.Attribute.MdxColumn); var converter = typeof(TypeConverter).GetMethod("ConvertFromString", new[] { typeof(string) }); var converterList = new TypeConverter[ps.Count()]; ps.For((v, i) => { var prop = v.PropertyInfo; var paramExp = Expression.Parameter(prop.PropertyType, prop.Name); var arrayAssignment = Expression.ArrayIndex(arrayExp, Expression.Constant(i)); var typeConverter = TypeDescriptor.GetConverter(prop.PropertyType); var converterArrayAssignment = Expression.ArrayIndex(converterArray, Expression.Constant(i)); var defaultValue = prop.PropertyType.GetDefault(); var defaultConstant = Expression.Constant(defaultValue == null ? null : defaultValue.ToString(), typeof(string)); var methodExp = Expression.Call(converterArrayAssignment, converter, Expression.Coalesce(arrayAssignment, defaultConstant)); Expression.Bind(prop, Expression.Convert(methodExp, prop.PropertyType)) .Finally(bind => bindingList.Add(paramExp, bind)); converterList[i] = typeConverter; }); var newExp = Expression.New(type); var memberInit = Expression.MemberInit(newExp, bindingList.Values.ToArray()); var lambda = Expression.Lambda <Func <TypeConverter[], string[], T> >(memberInit, new[] { converterArray, arrayExp }); var creator = lambda.Compile(); foreach (var flat in flattend) { var results = flat.MeasureValues .Select(x => new { Name = x.Key, Value = x.Value == null ? null : x.Value.ToString() }) .Concat(flat.PositionValues .Select(x => new { Name = x.Key, Value = x.Value })) .OrderBy(x => x.Name) .Select(x => x.Value) .ToArray(); yield return(creator(converterList, results)); } }