protected Type GetCollectionElementType(ParsedPropertyElement collectionElement) { var types = collectionElement.PropertyInfo.PropertyType.GetGenericArguments(); if (types.Length == 1) { return(types[0]); } throw new DynamicQueryException($"Unsupported collection type {collectionElement.PropertyInfo.Name} of collection {collectionElement.PropertyName}"); }
protected ExpressionPart CreateExpressionPart(Type lastCollectionElementType, Queue <ParsedPropertyElement> elements, int index, ParameterExpression rootParameter) { ParameterExpression collectionLambdaParameter = index == 0 && rootParameter != null ? rootParameter : Expression.Parameter(lastCollectionElementType, "p" + index); ParsedPropertyElement element; MemberExpression memberAccess = null; ParsedPropertyElement collectionElement = null; while (true) { element = elements.Dequeue(); if (element.PropertyType == PropertyType.Collection) { collectionElement = element; } if (element.PropertyType == PropertyType.CollectionFunction) { break; } memberAccess = Expression.MakeMemberAccess(collectionLambdaParameter, element.PropertyInfo); if (elements.Count == 0) { break; } var nextItem = elements.Peek(); if (element.PropertyType == PropertyType.Collection && nextItem.PropertyType != PropertyType.CollectionFunction) { break; } } return(new ExpressionPart { CollectionElement = collectionElement, LastPartElement = element, MemberAccess = memberAccess, Parameter = collectionLambdaParameter }); }
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); }
protected MethodInfo GetMethodInfo(ParsedPropertyElement collectionElement, KnownFunctions function) { var method = collectionElement.PropertyInfo.PropertyType.GetMethod(function.ToString()); return(method); }