internal override void Initialize() { foreach (TreeNode treeNode in this.OwnerNode.Ancestors(true)) { DataElementsTreeNode dataElementsTreeNode = treeNode as DataElementsTreeNode; if (dataElementsTreeNode != null && dataElementsTreeNode.InterfaceType == this.ParentFilterType) { this.ParentFilterTypeTreeNode = dataElementsTreeNode; break; } } bool dataItemAttachmentPointExists = this.OwnerNode.Tree.AttachmentPoints.OfType <IDataItemAttachmentPoint>().Any(f => f.InterfaceType == this.ParentFilterType) || this.OwnerNode.Tree.PossibleAttachmentPoints.OfType <IDataItemAttachmentPoint>().Any(f => f.InterfaceType == this.ParentFilterType); if (this.ParentFilterTypeTreeNode != null || dataItemAttachmentPointExists) { this.KeyPropertyInfo = this.ParentFilterType.GetKeyProperties()[0]; } if (this.KeyPropertyInfo == null) { AddValidationError("TreeValidationError.ParentIdFilterNode.TypeIsNotInParentTree", this.ParentFilterType); } this.ReferencePropertyInfo = this.OwnerNode.InterfaceType.GetPropertiesRecursively().SingleOrDefault(f => f.Name == this.ReferenceFieldName); if (this.ReferencePropertyInfo == null) { AddValidationError("TreeValidationError.Common.MissingProperty", this.OwnerNode.InterfaceType, this.ReferenceFieldName); } }
/// <exclude /> public void SetOwnerNode(TreeNode treeNode) { this.OwnerNode = (DataElementsTreeNode)treeNode; }
private static Expression CreateInnerExpression(TreeNodeDynamicContext dynamicContext, ParentIdFilterNode parentIdFilterNode, DataElementsTreeNode dataElementsTreeNode, bool includeJoin = true) { Type interfaceType = dataElementsTreeNode.CurrentDataInterfaceType; ParameterExpression parameterExpression = Expression.Parameter(interfaceType, "innerData"); List <int> filtersToSkip = new List <int>() { parentIdFilterNode.Id }; foreach (ParentIdFilterNode childParentIdFilterNode in dataElementsTreeNode.FilterNodes.OfType <ParentIdFilterNode>().Where(f => f.Id != parentIdFilterNode.Id)) { if (childParentIdFilterNode.ParentFilterTypeTreeNode.IsAncestor(parentIdFilterNode.ParentFilterTypeTreeNode)) { filtersToSkip.Add(childParentIdFilterNode.Id); } } Expression filterExpression = dataElementsTreeNode.CreateAccumulatedFilterExpression(parameterExpression, interfaceType, dynamicContext, filtersToSkip); Expression whereExpression = ExpressionHelper.CreateWhereExpression(DataFacade.GetData(interfaceType).Expression, parameterExpression, filterExpression); if ((includeJoin) && (dataElementsTreeNode.JoinDataElementsTreeNode != null)) { //MRJ: Multiple Parent Filter: Recursive call, so we would have to make multiple recursive calls Expression innerInnerExpression = CreateInnerExpression(dynamicContext, dataElementsTreeNode.JoinParentIdFilterNode, dataElementsTreeNode.JoinDataElementsTreeNode); // Create join lambda expressions PropertyInfo outerKeyPropertyInfo = dataElementsTreeNode.KeyPropertyInfo; LambdaExpression outerKeySelectorExpression = Expression.Lambda(Expression.Property(parameterExpression, outerKeyPropertyInfo), parameterExpression); Type innerKeyType = TypeHelpers.FindElementType(innerInnerExpression); ParameterExpression innerKeySelectorParameterExpression = Expression.Parameter(innerKeyType, "innerKeyParam"); LambdaExpression innerKeySelectorExpression = Expression.Lambda(innerKeySelectorParameterExpression, innerKeySelectorParameterExpression); ParameterExpression parameterExpression1 = Expression.Parameter(dataElementsTreeNode.CurrentDataInterfaceType, "param1"); ParameterExpression parameterExpression2 = Expression.Parameter(outerKeyPropertyInfo.PropertyType, "param2"); LambdaExpression resultSelector = Expression.Lambda(parameterExpression1, parameterExpression1, parameterExpression2); Expression joinExpression = ExpressionHelper.CreateJoinExpression( whereExpression, innerInnerExpression, outerKeySelectorExpression, innerKeySelectorExpression, resultSelector); whereExpression = joinExpression; } Expression selectExpression = ExpressionHelper.CreateSelectExpression(whereExpression, ExpressionHelper.CreatePropertyExpression(parentIdFilterNode.ReferenceFieldName, parameterExpression), parameterExpression); Expression distinctExpression = ExpressionHelper.CreateDistinctExpression(selectExpression); return(distinctExpression); }
/// <summary> /// This method finds the callers tree node own entity token by searching up/down using filters. /// In some cases this can be expensive. /// </summary> /// <param name="treeNode"></param> /// <param name="entityToken"></param> /// <param name="dynamicContext"></param> /// <returns></returns> private EntityToken FindOwnEntityToken(TreeNode treeNode, EntityToken entityToken, TreeNodeDynamicContext dynamicContext) { DataElementsTreeNode dataElementsTreeNode = treeNode as DataElementsTreeNode; if (dataElementsTreeNode != null) { if (dataElementsTreeNode.InterfaceType == this.OwnerNode.InterfaceType) // We found it :) { return(entityToken); } } TreeDataFieldGroupingElementEntityToken dataFieldGroupingElementEntityToken = entityToken as TreeDataFieldGroupingElementEntityToken; if (dataFieldGroupingElementEntityToken != null) // Search 'downwards' { ParameterExpression parameterExpression = Expression.Parameter(this.OwnerNode.InterfaceType, "data"); DataKeyPropertyCollection dataKeyPropertyCollection = new DataKeyPropertyCollection(); dataKeyPropertyCollection.AddKeyProperty("Id", dataFieldGroupingElementEntityToken.ChildGeneratingDataElementsReferenceValue); Type dataType = dataFieldGroupingElementEntityToken.ChildGeneratingDataElementsReferenceType; IData parentData = DataFacade.GetDataByUniqueKey(dataType, dataKeyPropertyCollection); TreeNodeDynamicContext dummyContext = new TreeNodeDynamicContext(TreeNodeDynamicContextDirection.Down); dummyContext.CustomData.Add("ParentData", parentData); IData resultData; if (this.OwnerNode.InterfaceType == TypeManager.GetType(dataFieldGroupingElementEntityToken.Type)) { Expression filterExpression = this.CreateDownwardsFilterExpression(parameterExpression, dummyContext); Expression whereExpression = ExpressionHelper.CreateWhereExpression(DataFacade.GetData(this.OwnerNode.InterfaceType).Expression, parameterExpression, filterExpression); resultData = (IData)DataFacade.GetData(this.OwnerNode.InterfaceType).Provider.CreateQuery(whereExpression).ToEnumerableOfObjects().First(); } else { resultData = parentData; } return(resultData.GetDataEntityToken()); } AncestorResult ancestorResult = treeNode.GetParentEntityToken(entityToken, this.ParentFilterType, dynamicContext); if ((this.OwnerNode.Id == ancestorResult.TreeNode.Id) || (this.OwnerNode.IsDescendant(ancestorResult.TreeNode))) // Search upwards { return(FindOwnEntityToken(ancestorResult.TreeNode, ancestorResult.EntityToken, dynamicContext)); } // Search 'downwards' by using the parent datas key value to get DataElementsTreeNode parentDataElementsTreeNode = (DataElementsTreeNode)ancestorResult.TreeNode; if (this.ParentFilterType == parentDataElementsTreeNode.InterfaceType) { DataEntityToken dataEntityToken = (DataEntityToken)ancestorResult.EntityToken; ParameterExpression parameterExpression = Expression.Parameter(this.OwnerNode.InterfaceType, "data"); TreeNodeDynamicContext dummyContext = new TreeNodeDynamicContext(TreeNodeDynamicContextDirection.Down); dummyContext.CustomData.Add("ParentData", dataEntityToken.Data); Expression filterExpression = this.CreateDownwardsFilterExpression(parameterExpression, dummyContext); Expression whereExpression = ExpressionHelper.CreateWhereExpression(DataFacade.GetData(this.OwnerNode.InterfaceType).Expression, parameterExpression, filterExpression); IData resultData = (IData)DataFacade.GetData(this.OwnerNode.InterfaceType).Provider.CreateQuery(whereExpression).ToEnumerableOfObjects().First(); return(resultData.GetDataEntityToken()); } throw new InvalidOperationException("Missing parent id filtering or try to simplify the parent id filterings (Unable to find own entity token)"); }
private static Expression CreateInnerExpression(TreeNodeDynamicContext dynamicContext, ParentIdFilterNode parentIdFilterNode, DataElementsTreeNode dataElementsTreeNode, bool includeJoin = true) { Type interfaceType = dataElementsTreeNode.CurrentDataInterfaceType; ParameterExpression parameterExpression = Expression.Parameter(interfaceType, "innerData"); List<int> filtersToSkip = new List<int>() { parentIdFilterNode.Id }; foreach (ParentIdFilterNode childParentIdFilterNode in dataElementsTreeNode.FilterNodes.OfType<ParentIdFilterNode>().Where(f => f.Id != parentIdFilterNode.Id)) { if (childParentIdFilterNode.ParentFilterTypeTreeNode.IsAncestor(parentIdFilterNode.ParentFilterTypeTreeNode)) { filtersToSkip.Add(childParentIdFilterNode.Id); } } Expression filterExpression = dataElementsTreeNode.CreateAccumulatedFilterExpression(parameterExpression, interfaceType, dynamicContext, filtersToSkip); Expression whereExpression = ExpressionHelper.CreateWhereExpression(DataFacade.GetData(interfaceType).Expression, parameterExpression, filterExpression); if ((includeJoin) && (dataElementsTreeNode.JoinDataElementsTreeNode != null)) { //MRJ: Multiple Parent Filter: Recursive call, so we would have to make multiple recursive calls Expression innerInnerExpression = CreateInnerExpression(dynamicContext, dataElementsTreeNode.JoinParentIdFilterNode, dataElementsTreeNode.JoinDataElementsTreeNode); // Create join lambda expressions PropertyInfo outerKeyPropertyInfo = dataElementsTreeNode.KeyPropertyInfo; LambdaExpression outerKeySelectorExpression = Expression.Lambda(Expression.Property(parameterExpression, outerKeyPropertyInfo), parameterExpression); Type innerKeyType = TypeHelpers.FindElementType(innerInnerExpression); ParameterExpression innerKeySelectorParameterExpression = Expression.Parameter(innerKeyType, "innerKeyParam"); LambdaExpression innerKeySelectorExpression = Expression.Lambda(innerKeySelectorParameterExpression, innerKeySelectorParameterExpression); ParameterExpression parameterExpression1 = Expression.Parameter(dataElementsTreeNode.CurrentDataInterfaceType, "param1"); ParameterExpression parameterExpression2 = Expression.Parameter(outerKeyPropertyInfo.PropertyType, "param2"); LambdaExpression resultSelector = Expression.Lambda(parameterExpression1, parameterExpression1, parameterExpression2); Expression joinExpression = ExpressionHelper.CreateJoinExpression( whereExpression, innerInnerExpression, outerKeySelectorExpression, innerKeySelectorExpression, resultSelector); whereExpression = joinExpression; } Expression selectExpression = ExpressionHelper.CreateSelectExpression(whereExpression, ExpressionHelper.CreatePropertyExpression(parentIdFilterNode.ReferenceFieldName, parameterExpression), parameterExpression); Expression distinctExpression = ExpressionHelper.CreateDistinctExpression(selectExpression); return distinctExpression; }