Exemplo n.º 1
0
        /// <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 InternalServicePropertyBuilder Attach([NotNull] InternalEntityTypeBuilder entityTypeBuilder = null)
        {
            var newPropertyBuilder = entityTypeBuilder.ServiceProperty(Metadata.GetIdentifyingMemberInfo(), Metadata.GetConfigurationSource());

            if (newPropertyBuilder == null)
            {
                return(null);
            }

            newPropertyBuilder.MergeAnnotationsFrom(Metadata);

            var oldParameterBindingConfigurationSource = Metadata.GetParameterBindingConfigurationSource();

            if (oldParameterBindingConfigurationSource.HasValue)
            {
                newPropertyBuilder.HasParameterBinding(Metadata.ParameterBinding, oldParameterBindingConfigurationSource.Value);
            }

            var oldFieldInfoConfigurationSource = Metadata.GetFieldInfoConfigurationSource();

            if (oldFieldInfoConfigurationSource.HasValue &&
                newPropertyBuilder.CanSetField(Metadata.FieldInfo, oldFieldInfoConfigurationSource))
            {
                newPropertyBuilder.HasField(Metadata.FieldInfo, oldFieldInfoConfigurationSource.Value);
            }

            return(newPropertyBuilder);
        }
        /// <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.GetRuntimeProperties().Values;

            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);
        }