protected Queue <ExpressionPart> CreateExpressionsQueue(ParsedPropertyPath propertyPath, Type collectionEntityType, ParameterExpression commonParameter = null) { //fill initial list var elements = new Queue <ParsedPropertyElement>(); foreach (var element in propertyPath.Elements) { elements.Enqueue(element); } //create resulting list var expressionParts = new Queue <ExpressionPart>(); var lastCollectionEntityType = collectionEntityType; var index = 0; while (elements.Count > 0) { var expressionPart = CreateExpressionPart(lastCollectionEntityType, elements, index, commonParameter); if (expressionPart.CollectionElement != null) { lastCollectionEntityType = GetCollectionElementType(expressionPart.CollectionElement); } expressionParts.Enqueue(expressionPart); index++; } return(expressionParts); }
public ParsedPropertyPath ParsePropertyOfType(string propertyPath, Type entityType) { if (string.IsNullOrWhiteSpace(propertyPath)) { throw new DynamicQueryException("Path to property can not be null or empty"); } var normalizedPath = propertyPath.ToLower(); var parsedPropertyPath = new ParsedPropertyPath(normalizedPath); var pathElements = normalizedPath.Split('.'); parsedPropertyPath.Elements = new List <ParsedPropertyElement>(pathElements.Length); var currentEntityType = entityType; ParsedPropertyElement lastElement = null; var applyToInternalObject = false; foreach (var pathElement in pathElements) { var isLastElementWasFunction = lastElement?.PropertyType == PropertyType.CollectionFunction; if (isLastElementWasFunction) { throw new DynamicQueryException($"Function '{lastElement.PropertyName}' should be last element in the property path"); } var propertyName = pathElement; var propertyType = PropertyType.Complex; var functionType = KnownFunctions.None; PropertyInfo propertyInfo = null; if (pathElement.Contains("[]")) { propertyType = PropertyType.Collection; propertyName = pathElement.Substring(0, pathElement.Length - 2); applyToInternalObject = true; } var isLastElementWasCollection = lastElement?.PropertyType == PropertyType.Collection; if (isLastElementWasCollection) { propertyType = applyToInternalObject ? PropertyType.Complex : PropertyType.CollectionFunction; applyToInternalObject = false; if (propertyType == PropertyType.CollectionFunction) { functionType = ParseFunction(propertyName); } } if (isLastElementWasCollection && propertyType != PropertyType.CollectionFunction) { currentEntityType = lastElement.PropertyInfo.PropertyType.GetGenericArguments().FirstOrDefault(); if (currentEntityType == null) { throw new DynamicQueryException($"Cannot get type of objects in collection '{lastElement.PropertyName}'"); } } if (propertyType != PropertyType.CollectionFunction) { propertyInfo = GetPropertyInfo(propertyName, currentEntityType); if (ReflectionHelper.IsCollection(propertyInfo.PropertyType)) { propertyType = PropertyType.Collection; } currentEntityType = propertyInfo.PropertyType; } lastElement = new ParsedPropertyElement { PropertyName = propertyName, PropertyType = propertyType, PropertyInfo = propertyInfo, RawElementName = pathElement, Function = functionType }; parsedPropertyPath.Elements.Add(lastElement); } if (lastElement?.PropertyType == PropertyType.Collection) { throw new DynamicQueryException("Array or Collection cannot be the last element in "); } if (lastElement?.PropertyType == PropertyType.Complex) { lastElement.PropertyType = PropertyType.Simple; } return(parsedPropertyPath); }