public static Type FindCandidateNavigationPropertyType(
            this PropertyInfo propertyInfo,
            ITypeMappingSource typeMappingSource,
            IParameterBindingFactories parameterBindingFactories)
        {
            var targetType         = propertyInfo.PropertyType;
            var targetSequenceType = targetType.TryGetSequenceType();

            if (!propertyInfo.IsCandidateProperty(targetSequenceType == null))
            {
                return(null);
            }

            targetType = targetSequenceType ?? targetType;
            targetType = targetType.UnwrapNullableType();

            if (targetType.GetTypeInfo().IsInterface ||
                targetType.GetTypeInfo().IsValueType ||
                targetType == typeof(object) ||
                parameterBindingFactories.FindFactory(propertyInfo.PropertyType, propertyInfo.Name) != null ||
                typeMappingSource.FindMapping(targetType) != null)
            {
                return(null);
            }

            return(targetType);
        }
        public static Type FindCandidateNavigationPropertyType(this PropertyInfo propertyInfo, Func <Type, bool> isPrimitiveProperty)
        {
            if (!propertyInfo.IsCandidateProperty())
            {
                return(null);
            }

            var targetType = propertyInfo.PropertyType;

            targetType = targetType.TryGetSequenceType() ?? targetType;
            targetType = targetType.UnwrapNullableType();

            if (isPrimitiveProperty(targetType) ||
                targetType.GetTypeInfo().IsInterface ||
                targetType.GetTypeInfo().IsValueType)
            {
                return(null);
            }

            return(targetType);
        }
        public static Type FindCandidateNavigationPropertyType(this PropertyInfo propertyInfo, Func <MemberInfo, bool> isPrimitiveProperty)
        {
            var targetType         = propertyInfo.PropertyType;
            var targetSequenceType = targetType.TryGetSequenceType();

            if (!propertyInfo.IsCandidateProperty(targetSequenceType == null))
            {
                return(null);
            }

            targetType = targetSequenceType ?? targetType;
            targetType = targetType.UnwrapNullableType();

            if (isPrimitiveProperty(propertyInfo) ||
                targetType.GetTypeInfo().IsInterface ||
                targetType.GetTypeInfo().IsValueType ||
                targetType == typeof(object))
            {
                return(null);
            }

            return(targetType);
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used 
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        protected override bool IsCandidatePrimitiveProperty(PropertyInfo propertyInfo)
        {
            Check.NotNull(propertyInfo, nameof(propertyInfo));

            return propertyInfo.IsCandidateProperty() && _typeMapper.IsTypeMapped(propertyInfo.PropertyType);
        }