예제 #1
0
        public ConventionSet ModifyConventions(ConventionSet conventionSet)
        {
            KeyDiscoveryConvention keyDiscoveryConvention = conventionSet.EntityTypeAddedConventions.OfType <KeyDiscoveryConvention>().Single();

            foreach (PropertyInfo propertyInfo in typeof(ConventionSet).GetProperties())
            {
                if (propertyInfo.GetValue(conventionSet) is IList list)
                {
                    list.Remove(keyDiscoveryConvention);
                }
            }
            return(conventionSet);
        }
        private void GenerateKeyAttribute(IProperty property)
        {
            var key = property.FindContainingPrimaryKey();

            if (key?.Properties.Count == 1)
            {
                if (key is IConventionKey concreteKey &&
                    key.Properties.SequenceEqual(KeyDiscoveryConvention.DiscoverKeyProperties(
                                                     concreteKey.DeclaringEntityType, concreteKey.DeclaringEntityType.GetProperties())))
                {
                    return;
                }

                if (key.GetName() != key.GetDefaultName())
                {
                    return;
                }

                _sb.AppendLine(new AttributeWriter(nameof(KeyAttribute)));
            }
        }
        private void GenerateKey(IKey key, IEntityType entityType, bool useDataAnnotations)
        {
            if (key == null)
            {
                var line = new List <string>
                {
                    $".{nameof(EntityTypeBuilder.HasNoKey)}()"
                };

                this.AppendMultiLineFluentApi(entityType, line);

                return;
            }

            var annotations = key.GetAnnotations().ToList();

            var explicitName = key.GetName() != key.GetDefaultName();

            RemoveAnnotation(ref annotations, RelationalAnnotationNames.Name);

            if (key.Properties.Count == 1 &&
                annotations.Count == 0)
            {
                if (key is Key concreteKey &&
                    key.Properties.SequenceEqual(
                        KeyDiscoveryConvention.DiscoverKeyProperties(
                            concreteKey.DeclaringEntityType,
                            concreteKey.DeclaringEntityType.GetProperties())))
                {
                    return;
                }

                if (!explicitName &&
                    useDataAnnotations)
                {
                    return;
                }
            }

            var lines = new List <string>
            {
                $".{nameof(EntityTypeBuilder.HasKey)}(e => {GenerateLambdaToKey(key.Properties, "e")})"
            };

            if (explicitName)
            {
                lines.Add(
                    $".{nameof(RelationalKeyBuilderExtensions.HasName)}" +
                    $"({this._code.Literal(key.GetName())})");
            }

            var annotationsToRemove = new List <IAnnotation>();

            foreach (var annotation in annotations)
            {
                if (annotation.Value == null ||
                    this._annotationCodeGenerator.IsHandledByConvention(key, annotation))
                {
                    annotationsToRemove.Add(annotation);
                }
                else
                {
                    var methodCall = this._annotationCodeGenerator.GenerateFluentApi(key, annotation);
                    if (methodCall != null)
                    {
                        lines.Add(this._code.Fragment(methodCall));
                        annotationsToRemove.Add(annotation);
                    }
                }
            }

            lines.AddRange(this.GenerateAnnotations(annotations.Except(annotationsToRemove)));

            this.AppendMultiLineFluentApi(key.DeclaringEntityType, lines);
        }
    /// <summary>
    ///     Builds and returns the convention set for the current database provider.
    /// </summary>
    /// <returns>The convention set for the current database provider.</returns>
    public virtual ConventionSet CreateConventionSet()
    {
        var conventionSet = new ConventionSet();

        var propertyDiscoveryConvention        = new PropertyDiscoveryConvention(Dependencies);
        var keyDiscoveryConvention             = new KeyDiscoveryConvention(Dependencies);
        var inversePropertyAttributeConvention = new InversePropertyAttributeConvention(Dependencies);
        var foreignKeyAttributeConvention      = new ForeignKeyAttributeConvention(Dependencies);
        var relationshipDiscoveryConvention    = new RelationshipDiscoveryConvention(Dependencies);
        var servicePropertyDiscoveryConvention = new ServicePropertyDiscoveryConvention(Dependencies);
        var indexAttributeConvention           = new IndexAttributeConvention(Dependencies);
        var baseTypeDiscoveryConvention        = new BaseTypeDiscoveryConvention(Dependencies);

        conventionSet.EntityTypeAddedConventions.Add(new NotMappedEntityTypeAttributeConvention(Dependencies));
        conventionSet.EntityTypeAddedConventions.Add(new OwnedEntityTypeAttributeConvention(Dependencies));
        conventionSet.EntityTypeAddedConventions.Add(new KeylessEntityTypeAttributeConvention(Dependencies));
        conventionSet.EntityTypeAddedConventions.Add(new EntityTypeConfigurationEntityTypeAttributeConvention(Dependencies));
        conventionSet.EntityTypeAddedConventions.Add(new NotMappedMemberAttributeConvention(Dependencies));
        conventionSet.EntityTypeAddedConventions.Add(baseTypeDiscoveryConvention);
        conventionSet.EntityTypeAddedConventions.Add(propertyDiscoveryConvention);
        conventionSet.EntityTypeAddedConventions.Add(servicePropertyDiscoveryConvention);
        conventionSet.EntityTypeAddedConventions.Add(keyDiscoveryConvention);
        conventionSet.EntityTypeAddedConventions.Add(indexAttributeConvention);
        conventionSet.EntityTypeAddedConventions.Add(inversePropertyAttributeConvention);
        conventionSet.EntityTypeAddedConventions.Add(foreignKeyAttributeConvention);
        conventionSet.EntityTypeAddedConventions.Add(relationshipDiscoveryConvention);

        conventionSet.EntityTypeIgnoredConventions.Add(relationshipDiscoveryConvention);

        var discriminatorConvention = new DiscriminatorConvention(Dependencies);

        conventionSet.EntityTypeRemovedConventions.Add(inversePropertyAttributeConvention);
        conventionSet.EntityTypeRemovedConventions.Add(discriminatorConvention);

        var foreignKeyIndexConvention = new ForeignKeyIndexConvention(Dependencies);
        var valueGeneratorConvention  = new ValueGenerationConvention(Dependencies);

        conventionSet.EntityTypeBaseTypeChangedConventions.Add(propertyDiscoveryConvention);
        conventionSet.EntityTypeBaseTypeChangedConventions.Add(servicePropertyDiscoveryConvention);
        conventionSet.EntityTypeBaseTypeChangedConventions.Add(keyDiscoveryConvention);
        conventionSet.EntityTypeBaseTypeChangedConventions.Add(indexAttributeConvention);
        conventionSet.EntityTypeBaseTypeChangedConventions.Add(inversePropertyAttributeConvention);
        conventionSet.EntityTypeBaseTypeChangedConventions.Add(relationshipDiscoveryConvention);
        conventionSet.EntityTypeBaseTypeChangedConventions.Add(foreignKeyIndexConvention);
        conventionSet.EntityTypeBaseTypeChangedConventions.Add(valueGeneratorConvention);
        conventionSet.EntityTypeBaseTypeChangedConventions.Add(discriminatorConvention);

        var foreignKeyPropertyDiscoveryConvention = new ForeignKeyPropertyDiscoveryConvention(Dependencies);

        conventionSet.EntityTypeMemberIgnoredConventions.Add(inversePropertyAttributeConvention);
        conventionSet.EntityTypeMemberIgnoredConventions.Add(relationshipDiscoveryConvention);
        conventionSet.EntityTypeMemberIgnoredConventions.Add(keyDiscoveryConvention);
        conventionSet.EntityTypeMemberIgnoredConventions.Add(foreignKeyPropertyDiscoveryConvention);

        var keyAttributeConvention = new KeyAttributeConvention(Dependencies);
        var backingFieldConvention = new BackingFieldConvention(Dependencies);
        var concurrencyCheckAttributeConvention    = new ConcurrencyCheckAttributeConvention(Dependencies);
        var databaseGeneratedAttributeConvention   = new DatabaseGeneratedAttributeConvention(Dependencies);
        var requiredPropertyAttributeConvention    = new RequiredPropertyAttributeConvention(Dependencies);
        var nonNullableReferencePropertyConvention = new NonNullableReferencePropertyConvention(Dependencies);
        var maxLengthAttributeConvention           = new MaxLengthAttributeConvention(Dependencies);
        var stringLengthAttributeConvention        = new StringLengthAttributeConvention(Dependencies);
        var timestampAttributeConvention           = new TimestampAttributeConvention(Dependencies);
        var backingFieldAttributeConvention        = new BackingFieldAttributeConvention(Dependencies);
        var unicodeAttributeConvention             = new UnicodeAttributeConvention(Dependencies);
        var precisionAttributeConvention           = new PrecisionAttributeConvention(Dependencies);

        conventionSet.PropertyAddedConventions.Add(backingFieldAttributeConvention);
        conventionSet.PropertyAddedConventions.Add(backingFieldConvention);
        conventionSet.PropertyAddedConventions.Add(concurrencyCheckAttributeConvention);
        conventionSet.PropertyAddedConventions.Add(databaseGeneratedAttributeConvention);
        conventionSet.PropertyAddedConventions.Add(requiredPropertyAttributeConvention);
        conventionSet.PropertyAddedConventions.Add(nonNullableReferencePropertyConvention);
        conventionSet.PropertyAddedConventions.Add(maxLengthAttributeConvention);
        conventionSet.PropertyAddedConventions.Add(stringLengthAttributeConvention);
        conventionSet.PropertyAddedConventions.Add(timestampAttributeConvention);
        conventionSet.PropertyAddedConventions.Add(keyAttributeConvention);
        conventionSet.PropertyAddedConventions.Add(keyDiscoveryConvention);
        conventionSet.PropertyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);
        conventionSet.PropertyAddedConventions.Add(unicodeAttributeConvention);
        conventionSet.PropertyAddedConventions.Add(precisionAttributeConvention);

        conventionSet.EntityTypePrimaryKeyChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);
        conventionSet.EntityTypePrimaryKeyChangedConventions.Add(valueGeneratorConvention);

        conventionSet.KeyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);
        conventionSet.KeyAddedConventions.Add(foreignKeyIndexConvention);

        conventionSet.KeyRemovedConventions.Add(foreignKeyPropertyDiscoveryConvention);
        conventionSet.KeyRemovedConventions.Add(foreignKeyIndexConvention);
        conventionSet.KeyRemovedConventions.Add(keyDiscoveryConvention);

        var cascadeDeleteConvention = new CascadeDeleteConvention(Dependencies);

        conventionSet.ForeignKeyAddedConventions.Add(foreignKeyAttributeConvention);
        conventionSet.ForeignKeyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);
        conventionSet.ForeignKeyAddedConventions.Add(keyDiscoveryConvention);
        conventionSet.ForeignKeyAddedConventions.Add(valueGeneratorConvention);
        conventionSet.ForeignKeyAddedConventions.Add(cascadeDeleteConvention);
        conventionSet.ForeignKeyAddedConventions.Add(foreignKeyIndexConvention);

        conventionSet.ForeignKeyRemovedConventions.Add(baseTypeDiscoveryConvention);
        conventionSet.ForeignKeyRemovedConventions.Add(relationshipDiscoveryConvention);
        conventionSet.ForeignKeyRemovedConventions.Add(keyDiscoveryConvention);
        conventionSet.ForeignKeyRemovedConventions.Add(valueGeneratorConvention);
        conventionSet.ForeignKeyRemovedConventions.Add(foreignKeyIndexConvention);

        conventionSet.ForeignKeyPropertiesChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);
        conventionSet.ForeignKeyPropertiesChangedConventions.Add(keyDiscoveryConvention);
        conventionSet.ForeignKeyPropertiesChangedConventions.Add(valueGeneratorConvention);
        conventionSet.ForeignKeyPropertiesChangedConventions.Add(foreignKeyIndexConvention);

        conventionSet.ForeignKeyUniquenessChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);
        conventionSet.ForeignKeyUniquenessChangedConventions.Add(keyDiscoveryConvention);
        conventionSet.ForeignKeyUniquenessChangedConventions.Add(foreignKeyIndexConvention);

        conventionSet.ForeignKeyRequirednessChangedConventions.Add(cascadeDeleteConvention);
        conventionSet.ForeignKeyRequirednessChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);

        conventionSet.ForeignKeyOwnershipChangedConventions.Add(new NavigationEagerLoadingConvention(Dependencies));
        conventionSet.ForeignKeyOwnershipChangedConventions.Add(relationshipDiscoveryConvention);
        conventionSet.ForeignKeyOwnershipChangedConventions.Add(keyDiscoveryConvention);
        conventionSet.ForeignKeyOwnershipChangedConventions.Add(valueGeneratorConvention);

        conventionSet.ForeignKeyNullNavigationSetConventions.Add(relationshipDiscoveryConvention);

        var requiredNavigationAttributeConvention = new RequiredNavigationAttributeConvention(Dependencies);
        var nonNullableNavigationConvention       = new NonNullableNavigationConvention(Dependencies);

        conventionSet.NavigationAddedConventions.Add(new NavigationBackingFieldAttributeConvention(Dependencies));
        conventionSet.NavigationAddedConventions.Add(backingFieldConvention);
        conventionSet.NavigationAddedConventions.Add(requiredNavigationAttributeConvention);
        conventionSet.NavigationAddedConventions.Add(nonNullableNavigationConvention);
        conventionSet.NavigationAddedConventions.Add(inversePropertyAttributeConvention);
        conventionSet.NavigationAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);
        conventionSet.NavigationAddedConventions.Add(relationshipDiscoveryConvention);
        conventionSet.NavigationAddedConventions.Add(foreignKeyAttributeConvention);

        var manyToManyJoinEntityTypeConvention = new ManyToManyJoinEntityTypeConvention(Dependencies);

        conventionSet.SkipNavigationAddedConventions.Add(new NavigationBackingFieldAttributeConvention(Dependencies));
        conventionSet.SkipNavigationAddedConventions.Add(backingFieldConvention);
        conventionSet.SkipNavigationAddedConventions.Add(manyToManyJoinEntityTypeConvention);

        conventionSet.SkipNavigationRemovedConventions.Add(manyToManyJoinEntityTypeConvention);

        conventionSet.SkipNavigationInverseChangedConventions.Add(manyToManyJoinEntityTypeConvention);
        conventionSet.SkipNavigationInverseChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);

        conventionSet.SkipNavigationForeignKeyChangedConventions.Add(manyToManyJoinEntityTypeConvention);
        conventionSet.SkipNavigationForeignKeyChangedConventions.Add(foreignKeyAttributeConvention);
        conventionSet.SkipNavigationForeignKeyChangedConventions.Add(keyDiscoveryConvention);
        conventionSet.SkipNavigationForeignKeyChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);

        conventionSet.NavigationRemovedConventions.Add(relationshipDiscoveryConvention);

        conventionSet.IndexAddedConventions.Add(foreignKeyIndexConvention);

        conventionSet.IndexRemovedConventions.Add(foreignKeyIndexConvention);

        conventionSet.IndexUniquenessChangedConventions.Add(foreignKeyIndexConvention);

        conventionSet.ForeignKeyPrincipalEndChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);
        conventionSet.ForeignKeyPrincipalEndChangedConventions.Add(requiredNavigationAttributeConvention);
        conventionSet.ForeignKeyPrincipalEndChangedConventions.Add(nonNullableNavigationConvention);

        conventionSet.PropertyNullabilityChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);

        conventionSet.PropertyFieldChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);
        conventionSet.PropertyFieldChangedConventions.Add(keyAttributeConvention);
        conventionSet.PropertyFieldChangedConventions.Add(concurrencyCheckAttributeConvention);
        conventionSet.PropertyFieldChangedConventions.Add(databaseGeneratedAttributeConvention);
        conventionSet.PropertyFieldChangedConventions.Add(requiredPropertyAttributeConvention);
        conventionSet.PropertyFieldChangedConventions.Add(nonNullableReferencePropertyConvention);
        conventionSet.PropertyFieldChangedConventions.Add(maxLengthAttributeConvention);
        conventionSet.PropertyFieldChangedConventions.Add(stringLengthAttributeConvention);
        conventionSet.PropertyFieldChangedConventions.Add(timestampAttributeConvention);

        conventionSet.ModelInitializedConventions.Add(new DbSetFindingConvention(Dependencies));

        conventionSet.ModelFinalizingConventions.Add(new ModelCleanupConvention(Dependencies));
        conventionSet.ModelFinalizingConventions.Add(keyAttributeConvention);
        conventionSet.ModelFinalizingConventions.Add(indexAttributeConvention);
        conventionSet.ModelFinalizingConventions.Add(foreignKeyAttributeConvention);
        conventionSet.ModelFinalizingConventions.Add(new ChangeTrackingStrategyConvention(Dependencies));
        conventionSet.ModelFinalizingConventions.Add(new ConstructorBindingConvention(Dependencies));
        conventionSet.ModelFinalizingConventions.Add(foreignKeyIndexConvention);
        conventionSet.ModelFinalizingConventions.Add(foreignKeyPropertyDiscoveryConvention);
        conventionSet.ModelFinalizingConventions.Add(nonNullableReferencePropertyConvention);
        conventionSet.ModelFinalizingConventions.Add(nonNullableNavigationConvention);
        conventionSet.ModelFinalizingConventions.Add(new QueryFilterRewritingConvention(Dependencies));
        conventionSet.ModelFinalizingConventions.Add(inversePropertyAttributeConvention);
        conventionSet.ModelFinalizingConventions.Add(backingFieldConvention);

        conventionSet.ModelFinalizedConventions.Add(new RuntimeModelConvention(Dependencies));

        return(conventionSet);
    }
예제 #5
0
        /// <summary>
        ///     Builds and returns the convention set for the current database provider.
        /// </summary>
        /// <returns> The convention set for the current database provider. </returns>
        public virtual ConventionSet CreateConventionSet()
        {
            var conventionSet = new ConventionSet();
            var logger        = Dependencies.Logger;

            var propertyDiscoveryConvention
                = new PropertyDiscoveryConvention(
                      Dependencies.TypeMappingSource, logger);

            var keyDiscoveryConvention
                = new KeyDiscoveryConvention(logger);

            var inversePropertyAttributeConvention
                = new InversePropertyAttributeConvention(Dependencies.MemberClassifier, logger);

            var relationshipDiscoveryConvention
                = new RelationshipDiscoveryConvention(Dependencies.MemberClassifier, logger);

            var servicePropertyDiscoveryConvention
                = new ServicePropertyDiscoveryConvention(Dependencies.TypeMappingSource, Dependencies.ParameterBindingFactories, logger);

            conventionSet.EntityTypeAddedConventions.Add(new NotMappedEntityTypeAttributeConvention(logger));
            conventionSet.EntityTypeAddedConventions.Add(new OwnedEntityTypeAttributeConvention(logger));
            conventionSet.EntityTypeAddedConventions.Add(new NotMappedMemberAttributeConvention(logger));
            conventionSet.EntityTypeAddedConventions.Add(new BaseTypeDiscoveryConvention(logger));
            conventionSet.EntityTypeAddedConventions.Add(propertyDiscoveryConvention);
            conventionSet.EntityTypeAddedConventions.Add(servicePropertyDiscoveryConvention);
            conventionSet.EntityTypeAddedConventions.Add(keyDiscoveryConvention);
            conventionSet.EntityTypeAddedConventions.Add(inversePropertyAttributeConvention);
            conventionSet.EntityTypeAddedConventions.Add(relationshipDiscoveryConvention);
            conventionSet.EntityTypeAddedConventions.Add(new DerivedTypeDiscoveryConvention(logger));

            conventionSet.EntityTypeIgnoredConventions.Add(inversePropertyAttributeConvention);

            var discriminatorConvention = new DiscriminatorConvention(logger);

            conventionSet.EntityTypeRemovedConventions.Add(new OwnedTypesConvention(logger));
            conventionSet.EntityTypeRemovedConventions.Add(discriminatorConvention);

            var foreignKeyIndexConvention = new ForeignKeyIndexConvention(logger);
            var valueGeneratorConvention  = new ValueGeneratorConvention(logger);

            conventionSet.EntityTypeBaseTypeChangedConventions.Add(propertyDiscoveryConvention);
            conventionSet.EntityTypeBaseTypeChangedConventions.Add(servicePropertyDiscoveryConvention);
            conventionSet.EntityTypeBaseTypeChangedConventions.Add(keyDiscoveryConvention);
            conventionSet.EntityTypeBaseTypeChangedConventions.Add(inversePropertyAttributeConvention);
            conventionSet.EntityTypeBaseTypeChangedConventions.Add(relationshipDiscoveryConvention);
            conventionSet.EntityTypeBaseTypeChangedConventions.Add(foreignKeyIndexConvention);
            conventionSet.EntityTypeBaseTypeChangedConventions.Add(valueGeneratorConvention);
            conventionSet.EntityTypeBaseTypeChangedConventions.Add(discriminatorConvention);

            var foreignKeyPropertyDiscoveryConvention = new ForeignKeyPropertyDiscoveryConvention(logger);

            conventionSet.EntityTypeMemberIgnoredConventions.Add(inversePropertyAttributeConvention);
            conventionSet.EntityTypeMemberIgnoredConventions.Add(relationshipDiscoveryConvention);
            conventionSet.EntityTypeMemberIgnoredConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.EntityTypeMemberIgnoredConventions.Add(servicePropertyDiscoveryConvention);

            var keyAttributeConvention = new KeyAttributeConvention(logger);
            var backingFieldConvention = new BackingFieldConvention(logger);
            var concurrencyCheckAttributeConvention    = new ConcurrencyCheckAttributeConvention(logger);
            var databaseGeneratedAttributeConvention   = new DatabaseGeneratedAttributeConvention(logger);
            var requiredPropertyAttributeConvention    = new RequiredPropertyAttributeConvention(logger);
            var nonNullableReferencePropertyConvention = new NonNullableReferencePropertyConvention(logger);
            var maxLengthAttributeConvention           = new MaxLengthAttributeConvention(logger);
            var stringLengthAttributeConvention        = new StringLengthAttributeConvention(logger);
            var timestampAttributeConvention           = new TimestampAttributeConvention(logger);

            conventionSet.PropertyAddedConventions.Add(backingFieldConvention);
            conventionSet.PropertyAddedConventions.Add(concurrencyCheckAttributeConvention);
            conventionSet.PropertyAddedConventions.Add(databaseGeneratedAttributeConvention);
            conventionSet.PropertyAddedConventions.Add(requiredPropertyAttributeConvention);
            conventionSet.PropertyAddedConventions.Add(nonNullableReferencePropertyConvention);
            conventionSet.PropertyAddedConventions.Add(maxLengthAttributeConvention);
            conventionSet.PropertyAddedConventions.Add(stringLengthAttributeConvention);
            conventionSet.PropertyAddedConventions.Add(timestampAttributeConvention);
            conventionSet.PropertyAddedConventions.Add(keyAttributeConvention);
            conventionSet.PropertyAddedConventions.Add(keyDiscoveryConvention);
            conventionSet.PropertyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);

            conventionSet.EntityTypePrimaryKeyChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.EntityTypePrimaryKeyChangedConventions.Add(valueGeneratorConvention);

            conventionSet.KeyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.KeyAddedConventions.Add(foreignKeyIndexConvention);

            conventionSet.KeyRemovedConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.KeyRemovedConventions.Add(foreignKeyIndexConvention);
            conventionSet.KeyRemovedConventions.Add(keyDiscoveryConvention);

            var cascadeDeleteConvention       = new CascadeDeleteConvention(logger);
            var foreignKeyAttributeConvention = new ForeignKeyAttributeConvention(Dependencies.MemberClassifier, logger);

            conventionSet.ForeignKeyAddedConventions.Add(foreignKeyAttributeConvention);
            conventionSet.ForeignKeyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.ForeignKeyAddedConventions.Add(keyDiscoveryConvention);
            conventionSet.ForeignKeyAddedConventions.Add(valueGeneratorConvention);
            conventionSet.ForeignKeyAddedConventions.Add(cascadeDeleteConvention);
            conventionSet.ForeignKeyAddedConventions.Add(foreignKeyIndexConvention);

            conventionSet.ForeignKeyRemovedConventions.Add(keyDiscoveryConvention);
            conventionSet.ForeignKeyRemovedConventions.Add(valueGeneratorConvention);
            conventionSet.ForeignKeyRemovedConventions.Add(foreignKeyIndexConvention);

            conventionSet.ForeignKeyPropertiesChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.ForeignKeyPropertiesChangedConventions.Add(keyDiscoveryConvention);
            conventionSet.ForeignKeyPropertiesChangedConventions.Add(valueGeneratorConvention);
            conventionSet.ForeignKeyPropertiesChangedConventions.Add(foreignKeyIndexConvention);

            conventionSet.ForeignKeyUniquenessChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.ForeignKeyUniquenessChangedConventions.Add(keyDiscoveryConvention);
            conventionSet.ForeignKeyUniquenessChangedConventions.Add(foreignKeyIndexConvention);

            conventionSet.ForeignKeyRequirednessChangedConventions.Add(cascadeDeleteConvention);
            conventionSet.ForeignKeyRequirednessChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);

            conventionSet.ForeignKeyOwnershipChangedConventions.Add(new NavigationEagerLoadingConvention(logger));
            conventionSet.ForeignKeyOwnershipChangedConventions.Add(keyDiscoveryConvention);
            conventionSet.ForeignKeyOwnershipChangedConventions.Add(relationshipDiscoveryConvention);

            conventionSet.ModelFinalizedConventions.Add(new ModelCleanupConvention(logger));
            conventionSet.ModelFinalizedConventions.Add(keyAttributeConvention);
            conventionSet.ModelFinalizedConventions.Add(foreignKeyAttributeConvention);
            conventionSet.ModelFinalizedConventions.Add(new ChangeTrackingStrategyConvention(logger));
            conventionSet.ModelFinalizedConventions.Add(new ConstructorBindingConvention(Dependencies.ConstructorBindingFactory, logger));
            conventionSet.ModelFinalizedConventions.Add(new TypeMappingConvention(Dependencies.TypeMappingSource, logger));
            conventionSet.ModelFinalizedConventions.Add(foreignKeyIndexConvention);

            conventionSet.ModelFinalizedConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.ModelFinalizedConventions.Add(servicePropertyDiscoveryConvention);

            conventionSet.NavigationAddedConventions.Add(backingFieldConvention);
            conventionSet.NavigationAddedConventions.Add(new RequiredNavigationAttributeConvention(logger));
            conventionSet.NavigationAddedConventions.Add(new NonNullableNavigationConvention(logger));
            conventionSet.NavigationAddedConventions.Add(inversePropertyAttributeConvention);
            conventionSet.NavigationAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.NavigationAddedConventions.Add(relationshipDiscoveryConvention);

            conventionSet.NavigationRemovedConventions.Add(relationshipDiscoveryConvention);

            conventionSet.IndexAddedConventions.Add(foreignKeyIndexConvention);

            conventionSet.IndexRemovedConventions.Add(foreignKeyIndexConvention);

            conventionSet.IndexUniquenessChangedConventions.Add(foreignKeyIndexConvention);

            conventionSet.ForeignKeyPrincipalEndChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);

            conventionSet.PropertyNullabilityChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);

            conventionSet.PropertyFieldChangedConventions.Add(keyDiscoveryConvention);
            conventionSet.PropertyFieldChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.PropertyFieldChangedConventions.Add(keyAttributeConvention);
            conventionSet.PropertyFieldChangedConventions.Add(concurrencyCheckAttributeConvention);
            conventionSet.PropertyFieldChangedConventions.Add(databaseGeneratedAttributeConvention);
            conventionSet.PropertyFieldChangedConventions.Add(requiredPropertyAttributeConvention);
            conventionSet.PropertyFieldChangedConventions.Add(nonNullableReferencePropertyConvention);
            conventionSet.PropertyFieldChangedConventions.Add(maxLengthAttributeConvention);
            conventionSet.PropertyFieldChangedConventions.Add(stringLengthAttributeConvention);
            conventionSet.PropertyFieldChangedConventions.Add(timestampAttributeConvention);

            return(conventionSet);
        }
        private void GenerateKey(IKey key, IEntityType entityType, bool useDataAnnotations, IndentedStringBuilder sb)
        {
            if (key == null)
            {
                if (!useDataAnnotations)
                {
                    var line = new List <string> {
                        $".{nameof(EntityTypeBuilder.HasNoKey)}()"
                    };

                    AppendMultiLineFluentApi(entityType, line, sb);
                }

                return;
            }

            var annotations = AnnotationCodeGenerator
                              .FilterIgnoredAnnotations(key.GetAnnotations())
                              .ToDictionary(a => a.Name, a => a);

            AnnotationCodeGenerator.RemoveAnnotationsHandledByConventions(key, annotations);

            var explicitName = key.GetName() != key.GetDefaultName();

            annotations.Remove(RelationalAnnotationNames.Name);

            if (key.Properties.Count == 1 &&
                annotations.Count == 0)
            {
                if (key is Key concreteKey &&
                    key.Properties.SequenceEqual(
                        KeyDiscoveryConvention.DiscoverKeyProperties(
                            concreteKey.DeclaringEntityType,
                            concreteKey.DeclaringEntityType.GetProperties())))
                {
                    return;
                }

                if (!explicitName &&
                    useDataAnnotations)
                {
                    return;
                }
            }

            var lines = new List <string>
            {
                $".{nameof(EntityTypeBuilder.HasKey)}(e => {GenerateLambdaToKey(key.Properties, "e", EntityTypeTransformationService.TransformPropertyName)})"
            };

            if (explicitName)
            {
                lines.Add(
                    $".{nameof(RelationalKeyBuilderExtensions.HasName)}" +
                    $"({CSharpHelper.Literal(key.GetName())})");
            }

            lines.AddRange(
                AnnotationCodeGenerator.GenerateFluentApiCalls(key, annotations).Select(m => CSharpHelper.Fragment(m))
                .Concat(GenerateAnnotations(annotations.Values)));

            AppendMultiLineFluentApi(key.DeclaringEntityType, lines, sb);
        }
예제 #7
0
        /// <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 ConventionSet CreateConventionSet()
        {
            var conventionSet = new ConventionSet();

            var propertyDiscoveryConvention     = new PropertyDiscoveryConvention();
            var keyDiscoveryConvention          = new KeyDiscoveryConvention();
            var relationshipDiscoveryConvention = new RelationshipDiscoveryConvention();

            conventionSet.EntityTypeAddedConventions.Add(new NotMappedEntityTypeAttributeConvention());
            conventionSet.EntityTypeAddedConventions.Add(new NotMappedMemberAttributeConvention());
            conventionSet.EntityTypeAddedConventions.Add(new BaseTypeDiscoveryConvention());
            conventionSet.EntityTypeAddedConventions.Add(propertyDiscoveryConvention);
            conventionSet.EntityTypeAddedConventions.Add(keyDiscoveryConvention);
            conventionSet.EntityTypeAddedConventions.Add(new InversePropertyAttributeConvention());
            conventionSet.EntityTypeAddedConventions.Add(relationshipDiscoveryConvention);
            conventionSet.EntityTypeAddedConventions.Add(new DerivedTypeDiscoveryConvention());

            conventionSet.BaseEntityTypeSetConventions.Add(propertyDiscoveryConvention);
            conventionSet.BaseEntityTypeSetConventions.Add(keyDiscoveryConvention);
            conventionSet.BaseEntityTypeSetConventions.Add(relationshipDiscoveryConvention);

            // An ambiguity might have been resolved
            conventionSet.EntityTypeMemberIgnoredConventions.Add(relationshipDiscoveryConvention);

            var keyAttributeConvention = new KeyAttributeConvention();
            var foreignKeyPropertyDiscoveryConvention = new ForeignKeyPropertyDiscoveryConvention();

            conventionSet.PropertyAddedConventions.Add(new ConcurrencyCheckAttributeConvention());
            conventionSet.PropertyAddedConventions.Add(new DatabaseGeneratedAttributeConvention());
            conventionSet.PropertyAddedConventions.Add(new RequiredPropertyAttributeConvention());
            conventionSet.PropertyAddedConventions.Add(new MaxLengthAttributeConvention());
            conventionSet.PropertyAddedConventions.Add(new StringLengthAttributeConvention());
            conventionSet.PropertyAddedConventions.Add(new TimestampAttributeConvention());
            conventionSet.PropertyAddedConventions.Add(keyDiscoveryConvention);
            conventionSet.PropertyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.PropertyAddedConventions.Add(keyAttributeConvention);

            var keyConvention = new KeyConvention();

            conventionSet.KeyAddedConventions.Add(keyConvention);

            conventionSet.PrimaryKeySetConventions.Add(keyConvention);

            var cascadeDeleteConvention = new CascadeDeleteConvention();

            conventionSet.ForeignKeyAddedConventions.Add(new ForeignKeyAttributeConvention());
            conventionSet.ForeignKeyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.ForeignKeyAddedConventions.Add(keyConvention);
            conventionSet.ForeignKeyAddedConventions.Add(cascadeDeleteConvention);

            conventionSet.ForeignKeyRemovedConventions.Add(keyConvention);

            conventionSet.ModelBuiltConventions.Add(new ModelCleanupConvention());
            conventionSet.ModelBuiltConventions.Add(keyAttributeConvention);
            conventionSet.ModelBuiltConventions.Add(new PropertyMappingValidationConvention());
            conventionSet.ModelBuiltConventions.Add(new RelationshipValidationConvention());

            conventionSet.NavigationAddedConventions.Add(new RequiredNavigationAttributeConvention());
            conventionSet.NavigationAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.NavigationAddedConventions.Add(relationshipDiscoveryConvention);

            conventionSet.NavigationRemovedConventions.Add(relationshipDiscoveryConvention);

            conventionSet.PropertyNullableChangedConventions.Add(cascadeDeleteConvention);

            conventionSet.PrincipalEndSetConventions.Add(foreignKeyPropertyDiscoveryConvention);

            return(conventionSet);
        }
예제 #8
0
        /// <summary>
        /// Create the template output
        /// </summary>
        public override string TransformText()
        {
            this.Write("using Microsoft.EntityFrameworkCore;\r\nusing Microsoft.EntityFrameworkCore.Metadat" +
                       "a.Builders;\r\nusing ");
            this.Write(this.ToStringHelper.ToStringWithCulture(ModelNamespace));
            this.Write(";\r\n\r\nnamespace ");
            this.Write(this.ToStringHelper.ToStringWithCulture(Namespace));
            this.Write("\r\n{\r\n    public class ");
            this.Write(this.ToStringHelper.ToStringWithCulture(EntityType.Name));
            this.Write("Configuration : IEntityTypeConfiguration<");
            this.Write(this.ToStringHelper.ToStringWithCulture(EntityType.Name));
            this.Write(">\r\n    {\r\n        public void Configure(EntityTypeBuilder<");
            this.Write(this.ToStringHelper.ToStringWithCulture(EntityType.Name));
            this.Write("> builder)\r\n        {\r\n");

            var primaryKey = EntityType.FindPrimaryKey();

            if (primaryKey == null)
            {
                this.Write("            builder.HasNoKey();\r\n\r\n");
            }
            else if (!Enumerable.SequenceEqual(
                         primaryKey.Properties,
                         KeyDiscoveryConvention.DiscoverKeyProperties(
                             (IConventionEntityType)primaryKey.DeclaringEntityType,
                             primaryKey.DeclaringEntityType.GetProperties().Cast <IConventionProperty>())))
            {
                this.Write("            builder.HasKey(");
                this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(primaryKey.Properties)));
                this.Write(");\r\n\r\n");
            }

            var schema         = EntityType.GetSchema();
            var scaffoldSchema = schema != null && schema != EntityType.Model.GetDefaultSchema();

            var tableName     = EntityType.GetTableName();
            var isView        = EntityType.FindAnnotation("Relational:ViewDefinition") != null;
            var scaffoldTable = scaffoldSchema || isView || tableName != (string)EntityType["Scaffolding:DbSetName"];

            if (scaffoldTable)
            {
                this.Write("            builder.");
                this.Write(this.ToStringHelper.ToStringWithCulture(isView ? "ToView" : "ToTable"));
                this.Write("(");
                this.Write(this.ToStringHelper.ToStringWithCulture(scaffoldSchema ? Code.Literal(schema) + ", " : ""));
                this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(tableName)));
                this.Write(");\r\n\r\n");
            }

            foreach (var index in EntityType.GetIndexes().Where(i => i.IsUnique))
            {
                this.Write("            builder.HasIndex(");
                this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(index.Properties)));
                this.Write(")\r\n                .IsUnique();\r\n\r\n");
            }

            foreach (var property in EntityType.GetProperties())
            {
                var originalGenerationEnvironment = GenerationEnvironment;
                GenerationEnvironment = new StringBuilder();

                var columnName = property.GetColumnName();
                if (columnName != property.Name)
                {
                    this.Write("                .HasColumnName(");
                    this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(columnName)));
                    this.Write(")\r\n");
                }

                var columnType = (string)property["Relational:ColumnType"];
                if (columnType != null)
                {
                    this.Write("                .HasColumnType(");
                    this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(columnType)));
                    this.Write(")\r\n");
                }

                if (property.IsUnicode() == false)
                {
                    this.Write("                .IsUnicode(false)\r\n");
                }

                if (property.IsFixedLength() == true)
                {
                    this.Write("                .IsFixedLength()\r\n");
                }

                if (property.GetDefaultValue() != null ||
                    property.GetDefaultValueSql() != null)
                {
                    this.Write("                .HasDefaultValue()\r\n");
                }

                if (property.GetComputedColumnSql() != null)
                {
                    this.Write("                .HasComputedColumnSql(");
                    this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(columnName)));
                    this.Write(")\r\n");
                }

                var valueGenerated = property.ValueGenerated;
                var isRowVersion   = false;
                if (((IConventionProperty)property).GetValueGeneratedConfigurationSource().HasValue &&
                    valueGenerated != RelationalValueGenerationConvention.GetValueGenerated(property))
                {
                    if (valueGenerated == ValueGenerated.OnAddOrUpdate &&
                        property.IsConcurrencyToken)
                    {
                        isRowVersion = true;

                        this.Write("                .IsRowVersion()\r\n");
                    }
                    else
                    {
                        this.Write("                .ValueGenerated");
                        this.Write(this.ToStringHelper.ToStringWithCulture(valueGenerated));
                        this.Write("()\r\n");
                    }
                }

                if (property.IsConcurrencyToken && !isRowVersion)
                {
                    this.Write("                .IsConcurrencyToken()\r\n");
                }

                var propertyConfiguration = GenerationEnvironment.ToString();
                GenerationEnvironment = originalGenerationEnvironment;

                if (propertyConfiguration.Length != 0)
                {
                    this.Write("            builder.Property(e => e.");
                    this.Write(this.ToStringHelper.ToStringWithCulture(property.Name));
                    this.Write(")\r\n                ");
                    this.Write(this.ToStringHelper.ToStringWithCulture(propertyConfiguration.Trim()));
                    this.Write(";\r\n\r\n");
                }
            }

            foreach (var foreignKey in EntityType.GetForeignKeys())
            {
                var originalGenerationEnvironment = GenerationEnvironment;
                GenerationEnvironment = new StringBuilder();

                if (!foreignKey.PrincipalKey.IsPrimaryKey())
                {
                    this.Write("                .HasPrincipalKey");
                    this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.IsUnique ? "<" + foreignKey.PrincipalEntityType.Name + ">" : ""));
                    this.Write("(");
                    this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(foreignKey.PrincipalKey.Properties)));
                    this.Write(")\r\n");
                }


                this.Write("                .HasForeignKey");
                this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.IsUnique ? "<" + foreignKey.DeclaringEntityType.Name + ">" : ""));
                this.Write("(");
                this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(foreignKey.Properties)));
                this.Write(")\r\n");


                var defaultDeleteBehavior = foreignKey.IsRequired ? DeleteBehavior.Cascade : DeleteBehavior.ClientSetNull;
                if (foreignKey.DeleteBehavior != defaultDeleteBehavior)
                {
                    this.Write("                .OnDelete(");
                    this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(foreignKey.DeleteBehavior)));
                    this.Write(")\r\n");
                }

                var relationshipConfiguration = GenerationEnvironment.ToString();
                GenerationEnvironment = originalGenerationEnvironment;


                this.Write("            builder.HasOne(");
                this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.DependentToPrincipal != null ? "d => d." + foreignKey.DependentToPrincipal.Name : ""));
                this.Write(").");
                this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.IsUnique ? "WithOne" : "WithMany"));
                this.Write("(");
                this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.PrincipalToDependent != null ? "p => p." + foreignKey.PrincipalToDependent.Name : ""));
                this.Write(")\r\n                ");
                this.Write(this.ToStringHelper.ToStringWithCulture(relationshipConfiguration.Trim()));
                this.Write(";\r\n\r\n");
            }

            this.Write("        }\r\n    }\r\n}\r\n");
            return(this.GenerationEnvironment.ToString());
        }
예제 #9
0
        private void GenerateKey(IKey?key, IEntityType entityType, bool useDataAnnotations)
        {
            if (key == null)
            {
                if (!useDataAnnotations)
                {
                    var line = new List <string> {
                        $".{nameof(EntityTypeBuilder.HasNoKey)}()"
                    };

                    AppendMultiLineFluentApi(entityType, line);
                }

                return;
            }

            var annotations = _annotationCodeGenerator
                              .FilterIgnoredAnnotations(key.GetAnnotations())
                              .ToDictionary(a => a.Name, a => a);

            _annotationCodeGenerator.RemoveAnnotationsHandledByConventions(key, annotations);

            var explicitName = key.GetName() != key.GetDefaultName();

            annotations.Remove(RelationalAnnotationNames.Name);

            if (key.Properties.Count == 1 &&
                annotations.Count == 0)
            {
                if (key is IConventionKey conventionKey &&
                    conventionKey.Properties.SequenceEqual(
                        KeyDiscoveryConvention.DiscoverKeyProperties(
                            conventionKey.DeclaringEntityType,
                            conventionKey.DeclaringEntityType.GetProperties())))
                {
                    return;
                }

                if (!explicitName &&
                    useDataAnnotations)
                {
                    return;
                }
            }

            var lines = new List <string> {
                $".{nameof(EntityTypeBuilder.HasKey)}({_code.Lambda(key.Properties, "e")})"
            };

            if (explicitName)
            {
                lines.Add(
                    $".{nameof(RelationalKeyBuilderExtensions.HasName)}({_code.Literal(key.GetName()!)})");
            }

            lines.AddRange(
                _annotationCodeGenerator.GenerateFluentApiCalls(key, annotations).Select(m => _code.Fragment(m))
                .Concat(GenerateAnnotations(annotations.Values)));

            AppendMultiLineFluentApi(key.DeclaringEntityType, lines);
        }
예제 #10
0
        /// <summary>
        /// Create the template output
        /// </summary>
        public override string TransformText()
        {
            this.Write("namespace ");
            this.Write(this.ToStringHelper.ToStringWithCulture(ConfigurationNamespace));
            this.Write("\r\n{\r\n    using Microsoft.EntityFrameworkCore;\r\n    using Microsoft.EntityFramewor" +
                       "kCore.Metadata.Builders;\r\n    using Microsoft.EntityFrameworkCore.Storage.ValueC" +
                       "onversion;\r\n    using ");
            this.Write(this.ToStringHelper.ToStringWithCulture(ModelNamespace));
            this.Write(";\r\n");

            var usingNamespaceEndIndex = GenerationEnvironment.Length;

            this.Write("\r\n");

            var entityTypeComment         = EntityType.GetComment();
            var originalEntityTypeComment = entityTypeComment?.ToString();
            var hasEntityClassInfo        = EntityClassInfo.TryGetInfo(ref entityTypeComment, out var entityClassInfo);

            if (entityTypeComment != null)
            {
                this.Write("    /// <summary>\r\n    /// ");
                this.Write(this.ToStringHelper.ToStringWithCulture(entityTypeComment));
                this.Write(" Configuration\r\n    /// </summary>\r\n");
            }

            this.Write("    public partial class ");
            this.Write(this.ToStringHelper.ToStringWithCulture(EntityConfigurationName));
            this.Write(" : IEntityTypeConfiguration<");
            this.Write(this.ToStringHelper.ToStringWithCulture(EntityClassName));
            this.Write(">\r\n    {\r\n        /// <summary>\r\n        /// Configure\r\n        /// </summary>\r\n " +
                       "       public void Configure(EntityTypeBuilder<");
            this.Write(this.ToStringHelper.ToStringWithCulture(EntityClassName));
            this.Write("> builder)\r\n        {\r\n");

            var primaryKey = EntityType.FindPrimaryKey();

            if (primaryKey == null)
            {
                this.Write("            builder.HasNoKey();\r\n\r\n");
            }
            else if (!Enumerable.SequenceEqual(
                         primaryKey.Properties,
                         KeyDiscoveryConvention.DiscoverKeyProperties(
                             (IConventionEntityType)primaryKey.DeclaringEntityType,
                             primaryKey.DeclaringEntityType.GetProperties().Cast <IConventionProperty>())))
            {
                this.Write("            builder.HasKey(");
                this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(primaryKey.Properties)));
                this.Write(")\r\n                .HasName(\"PRIMARY\");\r\n\r\n");
            }
            if (!UseDataAnnotations)
            {
                var schema         = EntityType.GetSchema();
                var scaffoldSchema = schema != null && schema != EntityType.Model.GetDefaultSchema();

                var tableName     = EntityType.GetTableName();
                var isView        = EntityType.FindAnnotation("Relational:ViewDefinition") != null;
                var scaffoldTable = scaffoldSchema || isView || tableName != (string)EntityType["Scaffolding:DbSetName"];

                if (scaffoldTable)
                {
                    this.Write("            builder.");
                    this.Write(this.ToStringHelper.ToStringWithCulture(isView ? "ToView" : "ToTable"));
                    this.Write("(");
                    this.Write(this.ToStringHelper.ToStringWithCulture(scaffoldSchema ? Code.Literal(schema) + ", " : string.Empty));
                    this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(tableName)));
                    this.Write(");\r\n\r\n");
                }
            }
            if (originalEntityTypeComment != null)
            {
                this.Write("            builder.HasComment(@\"");
                this.Write(this.ToStringHelper.ToStringWithCulture(originalEntityTypeComment.Replace("\"", "\"\"")));
                this.Write("\");\r\n\r\n");
            }

            foreach (var index in EntityType.GetIndexes())
            {
                this.Write("            builder.HasIndex(");
                this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(index.Properties)));
                this.Write(")\r\n");

                if (index.IsUnique)
                {
                    this.Write("                .IsUnique()\r\n");
                }

                this.Write("                .HasName(\"");
                this.Write(this.ToStringHelper.ToStringWithCulture(index.GetName()));
                this.Write("\");\r\n\r\n");
            }

            var usingNamespaceSet = new HashSet <string>();

            foreach (var property in EntityType.GetProperties())
            {
                var originalGenerationEnvironment = GenerationEnvironment;
                GenerationEnvironment = new StringBuilder();

                var propertyComment         = property.GetComment();
                var originalPropertyComment = propertyComment?.ToString();
                var hasEntityPropertyInfo   = EntityPropertyInfo.TryGetInfo(ref propertyComment, out var entityPropertyInfo);

                var columnName = property.GetColumnName();
                if (!UseDataAnnotations)
                {
                    if (columnName != property.Name)
                    {
                        this.Write("                .HasColumnName(");
                        this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(columnName)));
                        this.Write(")\r\n");
                    }

                    var columnType = (string)property["Relational:ColumnType"];
                    if (columnType != null)
                    {
                        this.Write("                .HasColumnType(");
                        this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(columnType)));
                        this.Write(")\r\n");
                    }

                    if (hasEntityPropertyInfo && entityPropertyInfo.Attributes?.Any() == true)
                    {
                        if (entityPropertyInfo.Attributes.Any(item => item.Code == "DatabaseGenerated(DatabaseGeneratedOption.Identity)"))
                        {
                            this.Write("                .ValueGeneratedOnAdd()\r\n");
                        }
                        if (entityPropertyInfo.Attributes.Any(item => item.Code == "DatabaseGenerated(DatabaseGeneratedOption.Computed)"))
                        {
                            this.Write("                .ValueGeneratedOnAddOrUpdate()\r\n");
                        }
                        if (entityPropertyInfo.Attributes.Any(item => item.Code == "DatabaseGenerated(DatabaseGeneratedOption.None)"))
                        {
                            this.Write("                .ValueGeneratedNever()\r\n");
                        }
                    }
                }

                if (property.IsUnicode() == false)
                {
                    this.Write("                .IsUnicode(false)\r\n");
                }

                if (property.IsFixedLength() == true)
                {
                    this.Write("                .IsFixedLength()\r\n");
                }

                var propertyDefaultValue = property.GetDefaultValue();
                if (propertyDefaultValue != null)
                {
                    this.Write("                .HasDefaultValue(");
                    this.Write(this.ToStringHelper.ToStringWithCulture(propertyDefaultValue));
                    this.Write(")\r\n");
                }

                var propertyDefaultValueSql = property.GetDefaultValueSql();
                if (propertyDefaultValueSql != null)
                {
                    this.Write("                .HasDefaultValueSql(");
                    this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(propertyDefaultValueSql)));
                    this.Write(")\r\n");
                }

                var propertyComputedColumnSql = property.GetComputedColumnSql();
                if (propertyComputedColumnSql != null)
                {
                    this.Write("                .HasComputedColumnSql(");
                    this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(propertyComputedColumnSql)));
                    this.Write(")\r\n");
                }

                var valueGenerated = property.ValueGenerated;
                var isRowVersion   = false;
                if (((IConventionProperty)property).GetValueGeneratedConfigurationSource().HasValue &&
                    valueGenerated != RelationalValueGenerationConvention.GetValueGenerated(property))
                {
                    if (valueGenerated == ValueGenerated.OnAddOrUpdate &&
                        property.IsConcurrencyToken)
                    {
                        isRowVersion = true;

                        this.Write("                .IsRowVersion()\r\n");
                    }
                    else
                    {
                        this.Write("                .ValueGenerated");
                        this.Write(this.ToStringHelper.ToStringWithCulture(valueGenerated));
                        this.Write("()\r\n");
                    }
                }

                if (property.IsConcurrencyToken && !isRowVersion)
                {
                    this.Write("                .IsConcurrencyToken()\r\n");
                }

                if (hasEntityPropertyInfo && entityPropertyInfo?.Enum != null)
                {
                    usingNamespaceSet.Add(entityPropertyInfo.Enum.UsingNamespace);
                    //https://docs.microsoft.com/zh-cn/ef/core/modeling/value-conversions

                    var propertyClrType    = property.ClrType;
                    var isNullableType     = propertyClrType.IsGenericType && propertyClrType.GetGenericTypeDefinition() == typeof(Nullable <>);
                    var ignoreNullableType = isNullableType ? propertyClrType.GetGenericArguments()[0] : propertyClrType;
                    if (ignoreNullableType == typeof(string))
                    {
                        this.Write("                .HasConversion(new EnumToStringConverter<");
                        this.Write(this.ToStringHelper.ToStringWithCulture(entityPropertyInfo.Enum.Name));
                        this.Write(">())\r\n");
                    }
                    else
                    {
                        this.Write("                .HasConversion(new EnumToNumberConverter<");
                        this.Write(this.ToStringHelper.ToStringWithCulture(entityPropertyInfo.Enum.Name));
                        this.Write(", ");
                        this.Write(this.ToStringHelper.ToStringWithCulture(Code.Reference(ignoreNullableType)));
                        this.Write(">())\r\n");
                    }
                }

                if (originalPropertyComment != null)
                {
                    this.Write("                .HasComment(@\"");
                    this.Write(this.ToStringHelper.ToStringWithCulture(originalPropertyComment.Replace("\"", "\"\"")));
                    this.Write("\")\r\n");
                }

                var propertyConfiguration = GenerationEnvironment.ToString();
                GenerationEnvironment = originalGenerationEnvironment;

                if (propertyConfiguration.Length != 0)
                {
                    this.Write("            builder.Property(e => e.");
                    this.Write(this.ToStringHelper.ToStringWithCulture(property.Name));
                    this.Write(")\r\n                ");
                    this.Write(this.ToStringHelper.ToStringWithCulture(propertyConfiguration.Trim()));
                    this.Write(";\r\n\r\n");
                }
            }

            if (usingNamespaceSet.Any())
            {
                foreach (var usingNamespace in usingNamespaceSet)
                {
                    if (string.IsNullOrWhiteSpace(usingNamespace))
                    {
                        continue;
                    }
                    var value  = usingNamespace;
                    var prefix = "using ";
                    var thus   = "    ";
                    if (!value.Trim().StartsWith(prefix))
                    {
                        value = string.Concat(thus, prefix, value);
                    }

                    var suffix = ";";
                    if (!value.Trim().EndsWith(suffix))
                    {
                        value = string.Concat(value, suffix);
                    }
                    value += "\r\n";

                    GenerationEnvironment.Insert(usingNamespaceEndIndex, value);
                    usingNamespaceEndIndex += value.Length;
                }
            }

            foreach (var foreignKey in EntityType.GetForeignKeys())
            {
                var originalGenerationEnvironment = GenerationEnvironment;
                GenerationEnvironment = new StringBuilder();

                if (!foreignKey.PrincipalKey.IsPrimaryKey())
                {
                    this.Write("                .HasPrincipalKey");
                    this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.IsUnique ? "<" + foreignKey.PrincipalEntityType.Name + ">" : string.Empty));
                    this.Write("(");
                    this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(foreignKey.PrincipalKey.Properties)));
                    this.Write(")\r\n");
                }


                this.Write("                .HasForeignKey");
                this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.IsUnique ? "<" + foreignKey.DeclaringEntityType.Name + ">" : string.Empty));
                this.Write("(");
                this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(foreignKey.Properties)));
                this.Write(")\r\n");


                var defaultDeleteBehavior = foreignKey.IsRequired ? DeleteBehavior.Cascade : DeleteBehavior.ClientSetNull;
                if (foreignKey.DeleteBehavior != defaultDeleteBehavior)
                {
                    this.Write("                .OnDelete(");
                    this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(foreignKey.DeleteBehavior)));
                    this.Write(")\r\n");
                }

                var relationshipConfiguration = GenerationEnvironment.ToString();
                GenerationEnvironment = originalGenerationEnvironment;


                this.Write("            builder.HasOne(");
                this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.DependentToPrincipal != null ? "d => d." + foreignKey.DependentToPrincipal.Name : string.Empty));
                this.Write(").");
                this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.IsUnique ? "WithOne" : "WithMany"));
                this.Write("(");
                this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.PrincipalToDependent != null ? "p => p." + foreignKey.PrincipalToDependent.Name : ""));
                this.Write(")\r\n                ");
                this.Write(this.ToStringHelper.ToStringWithCulture(relationshipConfiguration.Trim()));
                this.Write(";\r\n\r\n");
            }

            this.Write("            ConfigurePartial(builder);\r\n        }\r\n\r\n        partial void Configu" +
                       "rePartial(EntityTypeBuilder<");
            this.Write(this.ToStringHelper.ToStringWithCulture(EntityClassName));
            this.Write("> builder);\r\n    }\r\n}\r\n");
            return(this.GenerationEnvironment.ToString());
        }
        /// <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 ConventionSet CreateConventionSet()
        {
            var conventionSet = new ConventionSet();

            var propertyDiscoveryConvention = new PropertyDiscoveryConvention();
            var keyDiscoveryConvention = new KeyDiscoveryConvention();
            var relationshipDiscoveryConvention = new RelationshipDiscoveryConvention();
            conventionSet.EntityTypeAddedConventions.Add(new NotMappedEntityTypeAttributeConvention());
            conventionSet.EntityTypeAddedConventions.Add(new NotMappedMemberAttributeConvention());
            conventionSet.EntityTypeAddedConventions.Add(new BaseTypeDiscoveryConvention());
            conventionSet.EntityTypeAddedConventions.Add(propertyDiscoveryConvention);
            conventionSet.EntityTypeAddedConventions.Add(keyDiscoveryConvention);
            conventionSet.EntityTypeAddedConventions.Add(new InversePropertyAttributeConvention());
            conventionSet.EntityTypeAddedConventions.Add(relationshipDiscoveryConvention);
            conventionSet.EntityTypeAddedConventions.Add(new DerivedTypeDiscoveryConvention());

            conventionSet.BaseEntityTypeSetConventions.Add(propertyDiscoveryConvention);
            conventionSet.BaseEntityTypeSetConventions.Add(keyDiscoveryConvention);
            conventionSet.BaseEntityTypeSetConventions.Add(relationshipDiscoveryConvention);

            // An ambiguity might have been resolved
            conventionSet.EntityTypeMemberIgnoredConventions.Add(relationshipDiscoveryConvention);

            var keyAttributeConvention = new KeyAttributeConvention();
            var foreignKeyPropertyDiscoveryConvention = new ForeignKeyPropertyDiscoveryConvention();
            conventionSet.PropertyAddedConventions.Add(new ConcurrencyCheckAttributeConvention());
            conventionSet.PropertyAddedConventions.Add(new DatabaseGeneratedAttributeConvention());
            conventionSet.PropertyAddedConventions.Add(new RequiredPropertyAttributeConvention());
            conventionSet.PropertyAddedConventions.Add(new MaxLengthAttributeConvention());
            conventionSet.PropertyAddedConventions.Add(new StringLengthAttributeConvention());
            conventionSet.PropertyAddedConventions.Add(new TimestampAttributeConvention());
            conventionSet.PropertyAddedConventions.Add(keyDiscoveryConvention);
            conventionSet.PropertyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.PropertyAddedConventions.Add(keyAttributeConvention);

            var keyConvention = new KeyConvention();
            conventionSet.KeyAddedConventions.Add(keyConvention);

            conventionSet.PrimaryKeySetConventions.Add(keyConvention);

            var cascadeDeleteConvention = new CascadeDeleteConvention();
            conventionSet.ForeignKeyAddedConventions.Add(new ForeignKeyAttributeConvention());
            conventionSet.ForeignKeyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.ForeignKeyAddedConventions.Add(keyConvention);
            conventionSet.ForeignKeyAddedConventions.Add(cascadeDeleteConvention);

            conventionSet.ForeignKeyRemovedConventions.Add(keyConvention);

            conventionSet.ModelBuiltConventions.Add(new ModelCleanupConvention());
            conventionSet.ModelBuiltConventions.Add(keyAttributeConvention);
            conventionSet.ModelBuiltConventions.Add(keyConvention);
            conventionSet.ModelBuiltConventions.Add(new PropertyMappingValidationConvention());
            conventionSet.ModelBuiltConventions.Add(new RelationshipValidationConvention());

            conventionSet.NavigationAddedConventions.Add(new RequiredNavigationAttributeConvention());
            conventionSet.NavigationAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);
            conventionSet.NavigationAddedConventions.Add(relationshipDiscoveryConvention);

            conventionSet.NavigationRemovedConventions.Add(relationshipDiscoveryConvention);

            conventionSet.PropertyNullableChangedConventions.Add(cascadeDeleteConvention);

            conventionSet.PrincipalEndSetConventions.Add(foreignKeyPropertyDiscoveryConvention);

            return conventionSet;
        }