//private IQueryable BuildGroupBy(IQueryable<TSource> query) //{ // MakeGroupByExpression(GroupingKeys.ToArray(), out Type keyType, out var expr); // IQueryable result = (IQueryable)TypicalLinqMethods.QueryableGroupBy // .MakeGenericMethod(typeof(TSource), keyType) // .Invoke(null, new object[] { query, expr }); // return result; //} internal static LambdaExpression MakeGroupByExpression(GroupingKey[] keys) { var parameter = Expression.Parameter(typeof(TSource)); int count = keys.Length; Type keyType; if (count == 0) { keys = new GroupingKey[] { GroupingKey.NoGroupingKey }; count = 1; } keyType = Type.GetType(typeof(GroupingKey).FullName + "`" + count, false); if (keyType == null) { throw new InvalidOperationException("Too many grouping keys, at most 9 keys are allowed."); } keyType = keyType.MakeGenericType(keys.Select(o => o.SourceSelector.ReturnType).ToArray()); MemberBinding[] bindings = new MemberBinding[count]; for (int i = 0; i < count; i++) { var key = keys[i]; key.PropertyName = "Item" + (i + 1); bindings[i] = Expression.Bind(keyType.GetProperty(key.PropertyName), AggregationHelper.ExtractExpression(key.SourceSelector, parameter)); } return(Expression.Lambda(Expression.MemberInit(Expression.New(keyType), bindings), parameter)); }
private object DefineGroupingProperty(TInput inputrow) { var gk = new GroupingKey(); foreach (var map in GroupingAttributeMapping) { gk?.GroupingObjectsByProperty.Add(map.PropNameInInput, GetValueFromInputObject(inputrow, map)); } return(gk); }
private object DefineGroupingPropertyFromAttributes(TInput inputrow) { var gk = new GroupingKey(); foreach (var propMap in AggTypeInfo.GroupColumns) { gk?.GroupingObjectsByProperty.Add(propMap.PropInOutput, propMap.PropInInput.GetValue(inputrow)); } return(gk); }
public override bool Equals(object obj) { GroupingKey comp = obj as GroupingKey; if (comp == null) { return(false); } bool equals = true; foreach (var map in GroupingObjectsByProperty) { equals &= (map.Value?.Equals(comp.GroupingObjectsByProperty[map.Key]) ?? true); } return(equals); }
private void Lift(GroupingKey[] keys, AggregationLevel level, Func <T, string> label) { if (keys != null) { for (int i = 0; i < keys.Length; i++) { var key = keys[i]; LambdaExpression source = key.SourceSelector, result = key.ResultSelector; if (source != null && LiftModelToViewItem(ref source) || result != null && LiftModelToViewItem(ref result)) { keys[i] = new GroupingKey(source, result); } } } else { keys = new GroupingKey[] { GroupingKey.NoGroupingKey } }; LambdaExpression groupBy = AggregationHelper <AggregationResultItem <T> > .MakeGroupByExpression(keys); var temp = TypicalLinqMethods.EnumerableGroupBy .MakeGenericMethod(typeof(AggregationResultItem <T>), groupBy.ReturnType) .Invoke(null, new object[] { Items, groupBy.Compile() }); var selectItem = MakeSelectExpression(groupBy, keys, level, label); MethodInfo method = TypicalLinqMethods.EnumerableSelect .MakeGenericMethod(selectItem.Parameters[0].Type, typeof(AggregationResultItem <T>)); var coll = (IEnumerable <AggregationResultItem <T> >)method.Invoke(null, new object[] { temp, selectItem.Compile() }); _items.Clear(); _items.AddRange(coll); AppendGeneration(); }
/// <summary> /// Group all DBOs and return the readouts /// </summary> /// <param name="myDBObjectStreams"></param> /// <param name="mySelections"></param> /// <param name="myReferencedDBType"></param> /// <returns></returns> private IEnumerable<Vertex> ExamineDBO_Groupings(IEnumerable<Exceptional<DBObjectStream>> myDBObjectStreams, List<SelectionElement> mySelections, GraphDBType myReferencedDBType) { #region Create groupings using the ILookup var _GroupedVertices = myDBObjectStreams.ToLookup((dbo) => { CheckLoadedDBObjectStream(dbo, myReferencedDBType); #region Create GroupingKey based on the group values and attributes var groupingVals = new Dictionary<GroupingValuesKey, IObject>(); foreach (var selection in mySelections) { if (!dbo.Value.HasAttribute(selection.Element, _DBContext)) { continue; } var attrValue = dbo.Value.GetAttribute(selection.Element, myReferencedDBType, _DBContext); if (attrValue.Failed()) { throw new GraphDBException(attrValue.IErrors); } groupingVals.Add(new GroupingValuesKey(selection.Element, selection.Alias), attrValue.Value); } GroupingKey groupingKey = new GroupingKey(groupingVals); #endregion return groupingKey; }, (dbo) => { CheckLoadedDBObjectStream(dbo, myReferencedDBType); return dbo.Value; }); #endregion foreach (var group in _GroupedVertices) { #region No valid grouping keys found if (group.Key.Values.IsNullOrEmpty()) { continue; } #endregion var groupedAttributes = new Dictionary<String, Object>(); foreach (var groupingKeyVal in group.Key.Values) { groupedAttributes.Add(groupingKeyVal.Key.AttributeAlias, groupingKeyVal.Value.GetReadoutValue()); } var _VertexGroup = new VertexGroup(groupedAttributes, group.Select(_DBObjectStream => new Vertex(GetAllSelectedAttributesFromVertex(_DBObjectStream, myReferencedDBType, -1, null, null, false, true)))); #region Check having if (_HavingExpression != null) { var res = _HavingExpression.IsSatisfyHaving(_VertexGroup, _DBContext); if (res.Failed()) throw new GraphDBException(res.IErrors); else if (res.Value) yield return _VertexGroup; } else { yield return _VertexGroup; } #endregion } }
/// <summary> /// Go through each DBO and aggregate them /// </summary> /// <param name="myAggregates"></param> /// <param name="mySelections"></param> /// <param name="myDBOs"></param> /// <param name="myReferencedDBType"></param> /// <returns></returns> private IEnumerable<Vertex> ExamineDBO_Aggregates(IEnumerable<Exceptional<DBObjectStream>> myDBOs, List<SelectionElementAggregate> myAggregates, List<SelectionElement> mySelections, GraphDBType myReferencedDBType, Boolean myUsingGraph) { #region Aggregate if (mySelections.CountIsGreater(0)) { #region Grouping - each selection is grouped (checked prior) var aggregatedGroupings = new Dictionary<GroupingKey, SelectionElementAggregate>(); #region Create groupings using the ILookup var groupedDBOs = myDBOs.ToLookup((dbo) => { CheckLoadedDBObjectStream(dbo, myReferencedDBType); #region Create GroupingKey based on the group values and attributes Dictionary<GroupingValuesKey, IObject> groupingVals = new Dictionary<GroupingValuesKey, IObject>(); foreach (var selection in mySelections) { var attrValue = dbo.Value.GetAttribute(selection.Element, myReferencedDBType, _DBContext); if (attrValue.Failed()) { throw new GraphDBException(attrValue.IErrors); } groupingVals.Add(new GroupingValuesKey(selection.Element, selection.Alias), attrValue.Value); } GroupingKey groupingKey = new GroupingKey(groupingVals); #endregion return groupingKey; }, (dbo) => { CheckLoadedDBObjectStream(dbo, myReferencedDBType); return dbo.Value; }); #endregion foreach (var group in groupedDBOs) { #region Create group readouts var aggregatedAttributes = new Dictionary<String, Object>(); foreach (var aggr in myAggregates) { var aggrResult = aggr.Aggregate.Aggregate(group as IEnumerable<DBObjectStream>, aggr.Element, _DBContext); if (aggrResult.Failed()) { throw new GraphDBException(aggrResult.IErrors); } aggregatedAttributes.Add(aggr.Alias, aggrResult.Value.GetReadoutValue()); } foreach (var groupingKeyVal in group.Key.Values) { aggregatedAttributes.Add(groupingKeyVal.Key.AttributeAlias, groupingKeyVal.Value.GetReadoutValue()); } var dbObjectReadout = new VertexGroup(aggregatedAttributes, (group as IEnumerable<DBObjectStream>).Select(dbo => new Vertex(GetAllSelectedAttributesFromVertex(dbo, myReferencedDBType, -1, null, null, false, true)))); #endregion #region Evaluate having if exist and yield return if (_HavingExpression != null) { var res = _HavingExpression.IsSatisfyHaving(dbObjectReadout, _DBContext); if (res.Failed()) throw new GraphDBException(res.IErrors); else if (res.Value) yield return dbObjectReadout; } else { yield return dbObjectReadout; } #endregion } yield break; #endregion } else { #region No grouping, just aggregates var aggregatedAttributes = new Dictionary<String, Object>(); Vertex _Vertex; if (!myUsingGraph && myAggregates.All(a => a.IndexAggregate != null)) { #region Index aggregates foreach (var aggr in myAggregates) { var idxAggrResult = aggr.Aggregate.Aggregate(aggr.IndexAggregate, myReferencedDBType, _DBContext); if (idxAggrResult.Failed()) { throw new GraphDBException(idxAggrResult.IErrors); } aggregatedAttributes.Add(aggr.Alias, idxAggrResult.Value.GetReadoutValue()); } _Vertex = new Vertex(aggregatedAttributes); #endregion } else { #region OR Attribute aggregates foreach (var aggr in myAggregates) { var curType = _DBContext.DBTypeManager.GetTypeByUUID(aggr.EdgeList.LastEdge.TypeUUID); var curAttr = curType.GetTypeAttributeByUUID(aggr.EdgeList.LastEdge.AttrUUID); var aggrResult = aggr.Aggregate.Aggregate(myDBOs.Select(dbo => { CheckLoadedDBObjectStream(dbo, curType, curAttr); return dbo.Value; }), aggr.Element, _DBContext); if (aggrResult.Failed()) { throw new GraphDBException(aggrResult.IErrors); } aggregatedAttributes.Add(aggr.Alias, aggrResult.Value.GetReadoutValue()); } _Vertex = new Vertex(aggregatedAttributes); #endregion } #region Check having expression and yield return value if (_HavingExpression != null) { var res = _HavingExpression.IsSatisfyHaving(_Vertex, _DBContext); if (res.Failed()) throw new GraphDBException(res.IErrors); else if (res.Value) yield return _Vertex; } else { yield return _Vertex; } #endregion yield break; #endregion } #endregion }
/// <summary> /// Group all DBOs and return the readouts /// </summary> /// <param name="myDBObjectStreams"></param> /// <param name="mySelections"></param> /// <param name="myReferencedDBType"></param> /// <returns></returns> private IEnumerable<IVertexView> ExamineDBO_Groupings(IEnumerable<IVertex> myDBObjectStreams, List<SelectionElement> mySelections) { #region Create groupings using the ILookup var _GroupedVertices = myDBObjectStreams.ToLookup((dbo) => { #region Create GroupingKey based on the group values and attributes var groupingVals = new Dictionary<GroupingValuesKey, IComparable>(); foreach (var selection in mySelections) { var attrValue = (selection.Element as IPropertyDefinition).GetValue(dbo); groupingVals.Add(new GroupingValuesKey(selection.Element, selection.Alias), attrValue); } GroupingKey groupingKey = new GroupingKey(groupingVals); #endregion return groupingKey; }, (dbo) => { return dbo; }); #endregion foreach (var group in _GroupedVertices) { #region No valid grouping keys found if (group.Key.Values.IsNullOrEmpty()) { continue; } #endregion var groupedAttributes = new Dictionary<String, Object>(); foreach (var groupingKeyVal in group.Key.Values) { groupedAttributes.Add(groupingKeyVal.Key.AttributeAlias, groupingKeyVal.Value); } var _VertexGroup = new VertexView(groupedAttributes, null); #region Check having if (_HavingExpression != null) { var res = _HavingExpression.IsSatisfyHaving(_VertexGroup); if (res) yield return _VertexGroup; } else { yield return _VertexGroup; } #endregion } }
/// <summary> /// Go through each DBO and aggregate them /// </summary> /// <param name="myAggregates"></param> /// <param name="mySelections"></param> /// <param name="myDBOs"></param> /// <param name="myReferencedDBType"></param> /// <returns></returns> private IEnumerable<IVertexView> ExamineDBO_Aggregates(Int64 myTransactionToken, SecurityToken mySecurityToken, IEnumerable<IVertex> myDBOs, List<SelectionElementAggregate> myAggregates, List<SelectionElement> mySelections, Boolean myUsingGraph, Int64 myDepth) { #region Aggregate if (mySelections.CountIsGreater(0)) { #region Grouping - each selection is grouped (checked prior) var aggregatedGroupings = new Dictionary<GroupingKey, SelectionElementAggregate>(); #region Create groupings using the ILookup var groupedDBOs = myDBOs.ToLookup((dbo) => { #region Create GroupingKey based on the group values and attributes Dictionary<GroupingValuesKey, IComparable> groupingVals = new Dictionary<GroupingValuesKey, IComparable>(); foreach (var selection in mySelections) { var attrValue = (selection.Element as IPropertyDefinition).GetValue(dbo); groupingVals.Add(new GroupingValuesKey(selection.Element, selection.Alias), attrValue); } GroupingKey groupingKey = new GroupingKey(groupingVals); #endregion return groupingKey; }, (dbo) => { return dbo; }); #endregion foreach (var group in groupedDBOs) { #region Create group readouts var aggregatedAttributes = new Dictionary<String, Object>(); foreach (var aggr in myAggregates) { var aggrResult = aggr.Aggregate.Aggregate( (group).Select( aVertex => (aggr.Element as IPropertyDefinition).GetValue(aVertex)), (IPropertyDefinition)aggr.Element); if (aggrResult.Value != null) { //aggregatedAttributes.Add(aggr.Alias, aggrResult.Value.Value.GetReadoutValue()); aggregatedAttributes.Add(aggr.Alias, ResolveAggregateResult(aggrResult, myDepth)); } } foreach (var groupingKeyVal in group.Key.Values) { aggregatedAttributes.Add(groupingKeyVal.Key.AttributeAlias, groupingKeyVal.Value); } var dbObjectReadout = new VertexView(aggregatedAttributes, null); #endregion #region Evaluate having if exist and yield return if (_HavingExpression != null) { var res = _HavingExpression.IsSatisfyHaving(dbObjectReadout); if (res) yield return dbObjectReadout; } else { yield return dbObjectReadout; } #endregion } yield break; #endregion } else { #region No grouping, just aggregates var aggregatedAttributes = new Dictionary<String, Object>(); VertexView _Vertex; #region OR Attribute aggregates foreach (var aggr in myAggregates) { FuncParameter aggrResult = null; if (aggr.Aggregate.PluginShortName == "count" && aggr.RelatedIDChainDefinition.SelectType == TypesOfSelect.Asterisk) { aggrResult = new FuncParameter(_graphdb.GetVertexCount<UInt64>(mySecurityToken, myTransactionToken, new RequestGetVertexCount(aggr.EdgeList.LastEdge.VertexTypeID), (stats, count) => count)); } else { aggrResult = aggr.Aggregate.Aggregate( myDBOs.Where(aVertex => (aggr.Element as IPropertyDefinition).HasValue(aVertex)).Select( dbo => (aggr.Element as IPropertyDefinition).GetValue(dbo)), (IPropertyDefinition)aggr.Element); } //aggregatedAttributes.Add(aggr.Alias, aggrResult.Value.GetReadoutValue()); if (aggrResult.Value != null) { aggregatedAttributes.Add(aggr.Alias, ResolveAggregateResult(aggrResult, myDepth)); } } _Vertex = new VertexView(aggregatedAttributes, null); #endregion #region Check having expression and yield return value if (_HavingExpression != null) { var res = _HavingExpression.IsSatisfyHaving(_Vertex); if (res) yield return _Vertex; } else { yield return _Vertex; } #endregion yield break; #endregion } #endregion }