private bool IsCandidateNavigationPropertyType( Type targetType, MemberInfo memberInfo, Model model, out bool?shouldBeOwned) { shouldBeOwned = null; var configuration = model.Configuration; var configurationType = configuration?.GetConfigurationType(targetType); var isConfiguredAsEntityType = configurationType.IsEntityType(); if (isConfiguredAsEntityType == false || !targetType.IsValidEntityType()) { return(false); } if (configurationType != null) { shouldBeOwned = configurationType == TypeConfigurationType.OwnedEntityType; } return(isConfiguredAsEntityType == true || (targetType != typeof(object) && _parameterBindingFactories.FindFactory(memberInfo.GetMemberType(), memberInfo.GetSimpleMemberName()) == null && _typeMappingSource.FindMapping(targetType, model) == null)); }
private void Process(IConventionEntityTypeBuilder entityTypeBuilder) { var entityType = entityTypeBuilder.Metadata; if (!entityType.HasClrType()) { return; } var candidates = entityType.GetRuntimeProperties().Values; foreach (var propertyInfo in candidates) { if (entityTypeBuilder.IsIgnored(propertyInfo.GetSimpleMemberName()) || ConventionEntityTypeExtensions.FindProperty(entityType, propertyInfo) != null || entityType.FindNavigation(propertyInfo) != null || !propertyInfo.IsCandidateProperty(publicOnly: false) || (propertyInfo.IsCandidateProperty() && _typeMappingSource.FindMapping(propertyInfo) != null)) { continue; } var factory = _parameterBindingFactories.FindFactory(propertyInfo.PropertyType, propertyInfo.GetSimpleMemberName()); if (factory == null) { continue; } var duplicateMap = GetDuplicateServiceProperties(entityType); if (duplicateMap != null && duplicateMap.TryGetValue(propertyInfo.PropertyType, out var duplicateServiceProperties)) { duplicateServiceProperties.Add(propertyInfo); return; } var otherServicePropertySameType = entityType.GetServiceProperties() .FirstOrDefault(p => p.ClrType == propertyInfo.PropertyType); if (otherServicePropertySameType != null) { if (ConfigurationSource.Convention.Overrides(otherServicePropertySameType.GetConfigurationSource())) { otherServicePropertySameType.DeclaringEntityType.RemoveServiceProperty(otherServicePropertySameType.Name); } AddDuplicateServiceProperty(entityTypeBuilder, propertyInfo); AddDuplicateServiceProperty(entityTypeBuilder, otherServicePropertySameType.GetIdentifyingMemberInfo()); return; } entityTypeBuilder.ServiceProperty(propertyInfo)?.HasParameterBinding( (ServiceParameterBinding)factory.Bind(entityType, propertyInfo.PropertyType, propertyInfo.GetSimpleMemberName())); } }
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); }
private bool TryBindConstructor( IEntityType entityType, ConstructorInfo constructor, Func <IParameterBindingFactory, IEntityType, Type, string, ParameterBinding> bind, out InstantiationBinding binding, out IEnumerable <ParameterInfo> unboundParameters) { IEnumerable <(ParameterInfo Parameter, ParameterBinding Binding)> bindings = constructor.GetParameters().Select( p => (p, string.IsNullOrEmpty(p.Name) ? null : _propertyFactory.FindParameter(entityType, p.ParameterType, p.Name) ?? bind(_factories.FindFactory(p.ParameterType, p.Name), entityType, p.ParameterType, p.Name))) .ToList(); if (bindings.Any(b => b.Binding == null)) { unboundParameters = bindings.Where(b => b.Binding == null).Select(b => b.Parameter); binding = null; return(false); } unboundParameters = null; binding = new ConstructorBinding(constructor, bindings.Select(b => b.Binding).ToList()); return(true); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual bool TryBindConstructor( IConventionEntityType entityType, ConstructorInfo constructor, out InstantiationBinding binding, out IEnumerable <ParameterInfo> unboundParameters) { IEnumerable <(ParameterInfo Parameter, ParameterBinding Binding)> bindings = constructor.GetParameters().Select( p => (p, _propertyFactory.TryBindParameter(entityType, p.ParameterType, p.Name) ?? _factories.FindFactory(p.ParameterType, p.Name)?.Bind(entityType, p.ParameterType, p.Name))) .ToList(); if (bindings.Any(b => b.Binding == null)) { unboundParameters = bindings.Where(b => b.Binding == null).Select(b => b.Parameter); binding = null; return(false); } unboundParameters = null; binding = new ConstructorBinding(constructor, bindings.Select(b => b.Binding).ToList()); return(true); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual Type FindCandidateNavigationPropertyType(MemberInfo memberInfo) { Check.NotNull(memberInfo, nameof(memberInfo)); var targetType = memberInfo.GetMemberType(); var targetSequenceType = targetType.TryGetSequenceType(); if (!(memberInfo is PropertyInfo propertyInfo) || !propertyInfo.IsCandidateProperty(targetSequenceType == null)) { return(null); } targetType = targetSequenceType ?? targetType; targetType = targetType.UnwrapNullableType(); return(targetType.GetTypeInfo().IsInterface || targetType.GetTypeInfo().IsValueType || targetType == typeof(object) || _parameterBindingFactories.FindFactory(targetType, memberInfo.GetSimpleMemberName()) != null || _typeMappingSource.FindMapping(targetType) != null || targetType.GetTypeInfo().IsArray ? null : 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> public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); var entityType = entityTypeBuilder.Metadata; if (entityType.HasClrType()) { var candidates = entityType.ClrType.GetRuntimeProperties(); foreach (var propertyInfo in candidates) { if (!(propertyInfo.IsCandidateProperty() && _typeMapper.FindMapping(propertyInfo) != null) && propertyInfo.IsCandidateProperty(publicOnly: false)) { var factory = _parameterBindingFactories.FindFactory(propertyInfo.PropertyType, propertyInfo.Name); if (factory != null) { var serviceProperty = entityType.FindServiceProperty(propertyInfo.Name); if (serviceProperty == null || serviceProperty.PropertyInfo != propertyInfo) { serviceProperty = entityType.AddServiceProperty(propertyInfo, ConfigurationSource.Convention); } serviceProperty.SetParameterBinding( (ServiceParameterBinding)factory.Bind(entityType, propertyInfo.PropertyType, propertyInfo.Name)); } } } } return(entityTypeBuilder); }
/// <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> public virtual Type FindCandidateNavigationPropertyType(PropertyInfo propertyInfo) { Check.NotNull(propertyInfo, nameof(propertyInfo)); 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); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual Type?FindCandidateNavigationPropertyType(MemberInfo memberInfo, ModelConfiguration?configuration) { var targetType = memberInfo.GetMemberType(); var targetSequenceType = targetType.TryGetSequenceType(); if (!(memberInfo is PropertyInfo propertyInfo) || !propertyInfo.IsCandidateProperty(targetSequenceType == null)) { return(null); } var isConfiguredAsEntityType = configuration?.GetConfigurationType(targetType).IsEntityType(); if (isConfiguredAsEntityType == false) { return(null); } if (targetSequenceType != null) { isConfiguredAsEntityType ??= configuration?.GetConfigurationType(targetSequenceType).IsEntityType(); if (isConfiguredAsEntityType == false) { return(null); } } targetType = targetSequenceType ?? targetType; if (!targetType.IsValidEntityType()) { return(null); } targetType = targetType.UnwrapNullableType(); return(isConfiguredAsEntityType == null && (targetType == typeof(object) || _parameterBindingFactories.FindFactory(targetType, memberInfo.GetSimpleMemberName()) != null || _typeMappingSource.FindMapping(targetType) != null) ? null : 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> public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); var entityType = entityTypeBuilder.Metadata; if (!entityType.HasClrType()) { return(entityTypeBuilder); } var candidates = entityType.ClrType.GetRuntimeProperties(); foreach (var propertyInfo in candidates) { if (entityTypeBuilder.IsIgnored(propertyInfo.Name, ConfigurationSource.Convention) || entityType.FindProperty(propertyInfo) != null || entityType.FindNavigation(propertyInfo) != null || !propertyInfo.IsCandidateProperty(publicOnly: false) || (propertyInfo.IsCandidateProperty() && _typeMappingSource.FindMapping(propertyInfo) != null)) { continue; } var factory = _parameterBindingFactories.FindFactory(propertyInfo.PropertyType, propertyInfo.Name); if (factory == null) { continue; } var duplicateMap = GetDuplicateServiceProperties(entityType); if (duplicateMap != null && duplicateMap.TryGetValue(propertyInfo.PropertyType, out var duplicateServiceProperties)) { duplicateServiceProperties.Add(propertyInfo); return(entityTypeBuilder); } var otherServicePropertySameType = entityType.GetServiceProperties() .FirstOrDefault(p => p.ClrType == propertyInfo.PropertyType); if (otherServicePropertySameType != null) { if (ConfigurationSource.Convention.Overrides(otherServicePropertySameType.GetConfigurationSource())) { otherServicePropertySameType.DeclaringEntityType.RemoveServiceProperty(otherServicePropertySameType.Name); } AddDuplicateServiceProperty(entityTypeBuilder, propertyInfo); AddDuplicateServiceProperty(entityTypeBuilder, otherServicePropertySameType.GetIdentifyingMemberInfo()); return(entityTypeBuilder); } entityTypeBuilder.ServiceProperty(propertyInfo, ConfigurationSource.Convention)?.SetParameterBinding( (ServiceParameterBinding)factory.Bind(entityType, propertyInfo.PropertyType, propertyInfo.Name), ConfigurationSource.Convention); } return(entityTypeBuilder); }