private void AddRootPropertyDetails(IncludeSecurityExpressionBuilder includeMetadata, Type typeUnderQuery, ParameterExpression parameterForTypeUnderQuery, string propertyPathSegment)
        {
            var currentProperty        = typeUnderQuery.GetProperty(propertyPathSegment);
            var propertyAccessMetadata = new IncludePathMetadataFragment(typeUnderQuery, currentProperty.PropertyType, Expression.MakeMemberAccess(parameterForTypeUnderQuery, currentProperty));

            includeMetadata.IncludedPropertyDetails.Add(propertyAccessMetadata);
        }
        private void AddNestedPropertyDetails(IncludeSecurityExpressionBuilder includeMetadata, string propertyPathSegment, IncludePathMetadataFragment previousIncludePathMetadataFragment)
        {
            var currentProperty        = previousIncludePathMetadataFragment.PropertySingularType.GetProperty(propertyPathSegment);
            var parameterExpression    = Expression.Parameter(previousIncludePathMetadataFragment.PropertySingularType);
            var propertyAccessMetadata = new IncludePathMetadataFragment(previousIncludePathMetadataFragment.PropertySingularType, currentProperty.PropertyType, Expression.MakeMemberAccess(parameterExpression, currentProperty));

            includeMetadata.IncludedPropertyDetails.Add(propertyAccessMetadata);
        }
        private void AddPropertyDetails(IncludeSecurityExpressionBuilder includeMetadata, Type typeUnderQuery, ParameterExpression parameterForTypeUnderQuery, string propertyPathSegment)
        {
            var previousMetadata = includeMetadata.IncludedPropertyDetails.LastOrDefault();

            if (previousMetadata == null)
            {
                // This is the root property.
                AddRootPropertyDetails(includeMetadata, typeUnderQuery, parameterForTypeUnderQuery, propertyPathSegment);
            }
            else
            {
                // This is a nested property.
                AddNestedPropertyDetails(includeMetadata, propertyPathSegment, previousMetadata);
            }
        }
        private void CollectIncludeMetaDatas(MethodCallExpression callNode)
        {
            var includedPropertyPath = GetIncludedPropertyPath(callNode); // Example:  "Entity.Property.Property"

            if (callNode.Object == null)
            {
                return;
            }

            var queryType = callNode.Object.Type;

            var includeMetadata            = new IncludeSecurityExpressionBuilder(includedPropertyPath);
            var typeUnderQuery             = queryType.ToSingleType();
            var parameterForTypeUnderQuery = Expression.Parameter(typeUnderQuery);

            var includedPropertyPathSegments = includedPropertyPath.Split('.'); // Example:  {"Entity", "Property", "Property"}

            foreach (var propertyPathSegment in includedPropertyPathSegments)
            {
                AddPropertyDetails(includeMetadata, typeUnderQuery, parameterForTypeUnderQuery, propertyPathSegment);
            }

            _metadatas.Add(includeMetadata);
        }