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); }
/// <exclude /> protected override void OnInitialize() { var parentNode = this.ParentNode as DataFolderElementsTreeNode; if (this.InterfaceType == null) { if (parentNode == null) { AddValidationError("TreeValidationError.DataFolderElements.MissingInterfaceType"); return; } this.InterfaceType = parentNode.InterfaceType; } else { if (!typeof(IData).IsAssignableFrom(this.InterfaceType)) { AddValidationError("TreeValidationError.Common.NotImplementingIData", this.InterfaceType, typeof(IData)); return; } if (parentNode != null && parentNode.InterfaceType != this.InterfaceType) { AddValidationError("TreeValidationError.DataFolderElements.WrongInterfaceType", this.InterfaceType, parentNode.InterfaceType); return; } } this.PropertyInfo = this.InterfaceType.GetPropertiesRecursively().SingleOrDefault(f => f.Name == this.FieldName); if (this.PropertyInfo == null) { AddValidationError("TreeValidationError.Common.MissingProperty", this.InterfaceType, this.FieldName); return; } if (this.DateFormat != null && this.PropertyInfo.PropertyType != typeof(DateTime)) { AddValidationError("TreeValidationError.DataFolderElements.DateFormetNotAllowed", this.FieldName, typeof(DateTime), this.PropertyInfo.PropertyType); } if (this.PropertyInfo.PropertyType == typeof(DateTime) && this.DateFormat == null) { AddValidationError("TreeValidationError.DataFolderElements.DateFormetIsMissing", this.FieldName); return; } this.DateTimeFormater = new DateTimeFormater(this.DateFormat); if (!string.IsNullOrEmpty(this.Range) && this.FirstLetterOnly) { AddValidationError("TreeValidationError.DataFolderElements.RangesAndFirstLetterOnlyNotAllowed"); } if (this.FirstLetterOnly && this.PropertyInfo.PropertyType != typeof(string)) { AddValidationError("TreeValidationError.DataFolderElements.WrongFirstLetterOnlyPropertyType", this.FieldName, typeof(string), this.PropertyInfo.PropertyType); } if (!string.IsNullOrEmpty(this.Range)) { this.FolderRanges = FolderRangesCreator.Create(this, this.Range, this.FieldName, this.PropertyInfo.PropertyType); } if (this.ChildNodes.OfType <DataElementsTreeNode>().Any(f => f.InterfaceType != this.InterfaceType)) { AddValidationError("TreeValidationError.DataFolderElements.WrongDateChildInterfaceType", this.InterfaceType); } this.SerializedInterfaceType = TypeManager.SerializeType(this.InterfaceType); this.AllGroupingNodes = new List <DataFolderElementsTreeNode>(); var usedPropertyNames = new List <string>(); var fieldTypes = new List <Type>(); DataFolderElementsTreeNode treeNode = this; int dataFolderElementCount = 0; while (treeNode != null) { dataFolderElementCount++; if (treeNode.InterfaceType != this.InterfaceType) { AddValidationError("TreeValidationError.DataFolderElements.InterfaceTypeSwitchNotAllowed", treeNode.InterfaceType, this.InterfaceType); break; } if (treeNode.PropertyInfo.PropertyType != typeof(DateTime)) { if (usedPropertyNames.Contains(treeNode.FieldName)) { AddValidationError("TreeValidationError.DataFolderElements.SameFieldUsedTwice", treeNode.FieldName); break; } usedPropertyNames.Add(treeNode.FieldName); } this.AllGroupingNodes.Add(treeNode); if (treeNode.FolderRanges != null) { fieldTypes.Add(typeof(int)); } else if (treeNode.PropertyInfo.PropertyType == typeof(DateTime)) { fieldTypes.Add(treeNode.DateTimeFormater.GetTupleConstructor().DeclaringType); } else { fieldTypes.Add(treeNode.PropertyInfo.PropertyType); } treeNode = treeNode.ParentNode as DataFolderElementsTreeNode; } Type type = GetTupleType(this.AllGroupingNodes.Count); type = type.MakeGenericType(fieldTypes.ToArray()); this.AllGroupingsTupleConstructor = type.GetConstructors().Single(); Type listType = typeof(List <>).MakeGenericType(this.InterfaceType); this.FolderIndexListAddMethodInfo = listType.GetMethods().Single(f => f.Name == "Add"); this.FolderIndexListClearMethodInfo = listType.GetMethods().Single(f => f.Name == "Clear"); this.FolderIndexListObject = Activator.CreateInstance(listType); this.FolderIndexListQueryable = ((IEnumerable)this.FolderIndexListObject).AsQueryable(); if (this.FieldName == null) { this.GroupingValuesFieldName = this.FieldName; } else { this.GroupingValuesFieldName = $"■{this.FieldName}_{dataFolderElementCount}"; } this.IsTopFolderParent = (this.ParentNode is DataFolderElementsTreeNode) == false; this.ChildGeneratingDataElementsTreeNode = this.DescendantsBreadthFirst().OfType <DataElementsTreeNode>().First(); IEnumerable <ParentIdFilterNode> parentIdFilterNodes = this.ChildGeneratingDataElementsTreeNode.FilterNodes.OfType <ParentIdFilterNode>(); if (parentIdFilterNodes.Count() <= 1) { this.ChildGeneratingParentIdFilterNode = this.ChildGeneratingDataElementsTreeNode.FilterNodes.OfType <ParentIdFilterNode>().SingleOrDefault(); } else { AddValidationError("TreeValidationError.DataFolderElements.TooManyParentIdFilters", treeNode.FieldName); } this.KeyPropertyInfo = this.InterfaceType.GetKeyProperties()[0]; if (!typeof(ILocalizedControlled).IsAssignableFrom(this.InterfaceType)) { this.ShowForeignItems = false; } }
/// <exclude /> protected override void OnInitialize() { if (!typeof(IData).IsAssignableFrom(this.InterfaceType)) { AddValidationError("TreeValidationError.Common.NotImplementingIData", this.InterfaceType, typeof(IData)); return; } IEnumerable <Type> siblingInterfaceTypes = this.ParentNode.ChildNodes.Where(f => f.GetType() == typeof(DataElementsTreeNode)).Select(f => ((DataElementsTreeNode)f).InterfaceType).ToList(); if (siblingInterfaceTypes.Count() != siblingInterfaceTypes.Distinct().Count()) { AddValidationError("TreeValidationError.DataElementsTreeNode.SameInterfaceUsedTwice", this.InterfaceType); return; } this.KeyPropertyInfo = this.CurrentDataInterfaceType.GetKeyProperties()[0]; foreach (ParentIdFilterNode parentIdFilterNode in this.FilterNodes.OfType <ParentIdFilterNode>()) { if (this.ParentFilteringHelpers == null) { this.ParentFilteringHelpers = new Dictionary <Type, ParentFilterHelper>(); } if (this.ParentFilteringHelpers.ContainsKey(parentIdFilterNode.ParentFilterType)) { AddValidationError("TreeValidationError.DataElementsTreeNode.SameParentFilterInterfaceUsedTwice", parentIdFilterNode.ParentFilterType); return; } var helper = new ParentFilterHelper { ParentIdFilterNode = parentIdFilterNode, ParentReferencedPropertyInfo = this.InterfaceType.GetPropertiesRecursively().Single(f => f.Name == parentIdFilterNode.ReferenceFieldName), ParentRefereePropertyName = parentIdFilterNode.ParentFilterType.GetKeyProperties()[0].Name }; this.ParentFilteringHelpers.Add(parentIdFilterNode.ParentFilterType, helper); } this.JoinParentIdFilterNode = null; this.JoinDataElementsTreeNode = null; foreach (TreeNode descendantTreeNode in this.DescendantsBreadthFirst()) { var dataElementTreeNode = descendantTreeNode as DataElementsTreeNode; if (dataElementTreeNode == null) { continue; } ParentIdFilterNode parentIdFilterNode = dataElementTreeNode.FilterNodes.OfType <ParentIdFilterNode>() .FirstOrDefault(f => f.ParentFilterType == this.InterfaceType); if (parentIdFilterNode != null) { if (this.JoinParentIdFilterNode == null) { this.JoinParentIdFilterNode = parentIdFilterNode; this.JoinDataElementsTreeNode = dataElementTreeNode; this.JoinInnerKeyReferencePropertyInfo = this.JoinDataElementsTreeNode.CurrentDataInterfaceType.GetAllProperties().Single(f => f.Name == this.JoinParentIdFilterNode.ReferenceFieldName); } else if (this.Display != LeafDisplayMode.Lazy) { AddValidationError("TreeValidationError.DataElementsTreeNode.MoreThanOnParentFilterIsPointingToMe", this.InterfaceType); return; } } } if (this.Label != null) { this.LabelDynamicValuesHelper = new DynamicValuesHelper(this.Label); this.LabelDynamicValuesHelper.Initialize(this); } if (this.ToolTip != null) { this.ToolTipDynamicValuesHelper = new DynamicValuesHelper(this.ToolTip); this.ToolTipDynamicValuesHelper.Initialize(this); } if (!typeof(ILocalizedControlled).IsAssignableFrom(this.InterfaceType)) { this.ShowForeignItems = false; } }
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; }