Example #1
0
        /// <summary>
        /// Returns the store value generation strategy to set for the given property.
        /// </summary>
        /// <param name="property"> The property. </param>
        /// <returns> The store value generation strategy to set for the given property. </returns>
        public static new ValueGenerated?GetValueGenerated([NotNull] IProperty property)
        {
            var valueGenerated = RelationalValueGenerationConvention.GetValueGenerated(property);

            if (valueGenerated != null)
            {
                return(valueGenerated);
            }

            var valueGenerationStrategy = property.GetValueGenerationStrategy();

            if (valueGenerationStrategy.HasValue)
            {
                switch (valueGenerationStrategy.Value)
                {
                case MySQLValueGenerationStrategy.IdentityColumn:
                    return(ValueGenerated.OnAdd);

                case MySQLValueGenerationStrategy.ComputedColumn:
                    return(ValueGenerated.OnAddOrUpdate);
                }
            }

            return(null);
        }
        /// <summary>
        ///     Builds and returns the convention set for the current database provider.
        /// </summary>
        /// <returns> The convention set for the current database provider. </returns>
        public override ConventionSet CreateConventionSet()
        {
            var conventionSet = base.CreateConventionSet();

            var relationalColumnAttributeConvention = new RelationalColumnAttributeConvention(Dependencies, RelationalDependencies);

            conventionSet.PropertyAddedConventions.Add(relationalColumnAttributeConvention);

            var tableNameFromDbSetConvention = new TableNameFromDbSetConvention(Dependencies, RelationalDependencies);

            conventionSet.EntityTypeAddedConventions.Add(new RelationalTableAttributeConvention(Dependencies, RelationalDependencies));
            conventionSet.EntityTypeAddedConventions.Add(tableNameFromDbSetConvention);

            ValueGenerationConvention valueGenerationConvention =
                new RelationalValueGenerationConvention(Dependencies, RelationalDependencies);

            ReplaceConvention(conventionSet.EntityTypeBaseTypeChangedConventions, valueGenerationConvention);
            conventionSet.EntityTypeBaseTypeChangedConventions.Add(tableNameFromDbSetConvention);

            conventionSet.EntityTypeAnnotationChangedConventions.Add((RelationalValueGenerationConvention)valueGenerationConvention);

            ReplaceConvention(conventionSet.EntityTypePrimaryKeyChangedConventions, valueGenerationConvention);

            ReplaceConvention(conventionSet.ForeignKeyAddedConventions, valueGenerationConvention);
            ReplaceConvention(conventionSet.ForeignKeyRemovedConventions, valueGenerationConvention);

            conventionSet.PropertyFieldChangedConventions.Add(relationalColumnAttributeConvention);

            var storeGenerationConvention = new StoreGenerationConvention(Dependencies, RelationalDependencies);

            conventionSet.PropertyAnnotationChangedConventions.Add(storeGenerationConvention);
            conventionSet.PropertyAnnotationChangedConventions.Add((RelationalValueGenerationConvention)valueGenerationConvention);

            var dbFunctionAttributeConvention = new RelationalDbFunctionAttributeConvention(Dependencies, RelationalDependencies);

            conventionSet.ModelInitializedConventions.Add(dbFunctionAttributeConvention);

            // ModelCleanupConvention would remove the entity types added by QueryableDbFunctionConvention #15898
            ConventionSet.AddAfter(
                conventionSet.ModelFinalizingConventions,
                new QueryableDbFunctionConvention(Dependencies, RelationalDependencies),
                typeof(ModelCleanupConvention));
            conventionSet.ModelFinalizingConventions.Add(dbFunctionAttributeConvention);
            conventionSet.ModelFinalizingConventions.Add(tableNameFromDbSetConvention);
            conventionSet.ModelFinalizingConventions.Add(storeGenerationConvention);
            conventionSet.ModelFinalizingConventions.Add(new SharedTableConvention(Dependencies, RelationalDependencies));
            conventionSet.ModelFinalizingConventions.Add(new DbFunctionTypeMappingConvention(Dependencies, RelationalDependencies));
            ReplaceConvention(
                conventionSet.ModelFinalizingConventions,
                (QueryFilterDefiningQueryRewritingConvention) new RelationalQueryFilterDefiningQueryRewritingConvention(
                    Dependencies, RelationalDependencies));

            ConventionSet.AddAfter(
                conventionSet.ModelFinalizedConventions,
                new RelationalModelConvention(Dependencies, RelationalDependencies),
                typeof(ValidatingConvention));

            return(conventionSet);
        }
        /// <summary>
        ///     Builds and returns the convention set for the current database provider.
        /// </summary>
        /// <returns> The convention set for the current database provider. </returns>
        public override ConventionSet CreateConventionSet()
        {
            var conventionSet = base.CreateConventionSet();

            ValueGenerationConvention valueGenerationConvention = new RelationalValueGenerationConvention(Dependencies, RelationalDependencies);

            ReplaceConvention(conventionSet.EntityTypeBaseTypeChangedConventions, valueGenerationConvention);
            ReplaceConvention(conventionSet.EntityTypePrimaryKeyChangedConventions, valueGenerationConvention);
            ReplaceConvention(conventionSet.ForeignKeyAddedConventions, valueGenerationConvention);
            ReplaceConvention(conventionSet.ForeignKeyRemovedConventions, valueGenerationConvention);

            var relationalColumnAttributeConvention = new RelationalColumnAttributeConvention(Dependencies, RelationalDependencies);

            conventionSet.PropertyAddedConventions.Add(relationalColumnAttributeConvention);

            var tableNameFromDbSetConvention = new TableNameFromDbSetConvention(Dependencies, RelationalDependencies);

            conventionSet.EntityTypeAddedConventions.Add(new RelationalTableAttributeConvention(Dependencies, RelationalDependencies));
            conventionSet.EntityTypeAddedConventions.Add(tableNameFromDbSetConvention);

            conventionSet.EntityTypeBaseTypeChangedConventions.Add(tableNameFromDbSetConvention);

            conventionSet.PropertyFieldChangedConventions.Add(relationalColumnAttributeConvention);

            var storeGenerationConvention = new StoreGenerationConvention(Dependencies, RelationalDependencies);

            conventionSet.PropertyAnnotationChangedConventions.Add(storeGenerationConvention);
            conventionSet.PropertyAnnotationChangedConventions.Add((RelationalValueGenerationConvention)valueGenerationConvention);

            var dbFunctionAttributeConvention = new RelationalDbFunctionAttributeConvention(Dependencies, RelationalDependencies);

            conventionSet.ModelInitializedConventions.Add(dbFunctionAttributeConvention);
            conventionSet.ModelAnnotationChangedConventions.Add(dbFunctionAttributeConvention);

            var sharedTableConvention = new SharedTableConvention(Dependencies, RelationalDependencies);

            ConventionSet.AddBefore(
                conventionSet.ModelFinalizedConventions,
                storeGenerationConvention,
                typeof(ValidatingConvention));
            ConventionSet.AddBefore(
                conventionSet.ModelFinalizedConventions,
                sharedTableConvention,
                typeof(ValidatingConvention));

            ConventionSet.AddBefore(
                conventionSet.ModelFinalizedConventions,
                new DbFunctionTypeMappingConvention(Dependencies, RelationalDependencies),
                typeof(ValidatingConvention));

            return(conventionSet);
        }
Example #4
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>
        protected virtual KeyBuilder VisitPrimaryKey([NotNull] EntityTypeBuilder builder, [NotNull] DatabaseTable table)
        {
            Check.NotNull(builder, nameof(builder));
            Check.NotNull(table, nameof(table));

            var primaryKey = table.PrimaryKey;

            var unmappedColumns = primaryKey.Columns
                                  .Where(c => _unmappedColumns.Contains(c))
                                  .Select(c => c.Name)
                                  .ToList();

            if (unmappedColumns.Count > 0)
            {
                _reporter.WriteWarning(
                    DesignStrings.PrimaryKeyErrorPropertyNotFound(
                        table.DisplayName(),
                        string.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator, unmappedColumns)));
                return(null);
            }

            var keyBuilder = builder.HasKey(primaryKey.Columns.Select(GetPropertyName).ToArray());


            if (primaryKey.Columns.Count == 1 &&
                primaryKey.Columns[0].ValueGenerated == null &&
                primaryKey.Columns[0].DefaultValueSql == null)
            {
                var property = builder.Metadata.FindProperty(GetPropertyName(primaryKey.Columns[0]))?.AsProperty();
                if (property != null)
                {
                    var conventionalValueGenerated = RelationalValueGenerationConvention.GetValueGenerated(property);
                    if (conventionalValueGenerated == ValueGenerated.OnAdd)
                    {
                        property.ValueGenerated = ValueGenerated.Never;
                    }
                }
            }

            if (!string.IsNullOrEmpty(primaryKey.Name) &&
                primaryKey.Name != keyBuilder.Metadata.GetDefaultName())
            {
                keyBuilder.HasName(primaryKey.Name);
            }

            keyBuilder.Metadata.AddAnnotations(primaryKey.GetAnnotations());

            return(keyBuilder);
        }
        protected virtual void GenerateProperty(IProperty property, bool useDataAnnotations)
        {
            var lines = this.Lines(property);

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

            RemoveAnnotation(ref annotations, RelationalAnnotationNames.ColumnName);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.ColumnType);
            RemoveAnnotation(ref annotations, CoreAnnotationNames.MaxLength);
            RemoveAnnotation(ref annotations, CoreAnnotationNames.TypeMapping);
            RemoveAnnotation(ref annotations, CoreAnnotationNames.Unicode);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.DefaultValue);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.DefaultValueSql);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.Comment);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.ComputedColumnSql);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.IsFixedLength);
            RemoveAnnotation(ref annotations, ScaffoldingAnnotationNames.ColumnOrdinal);

            if (!useDataAnnotations)
            {
                if (!property.IsNullable &&
                    property.ClrType.IsNullableType() &&
                    !property.IsPrimaryKey())
                {
                    lines.Add($".{nameof(PropertyBuilder.IsRequired)}()");
                }

                var columnName = property.GetColumnName();

                if (columnName != null &&
                    columnName != property.Name)
                {
                    lines.Add(
                        $".{nameof(RelationalPropertyBuilderExtensions.HasColumnName)}" +
                        $"({this._code.Literal(columnName)})");
                }

                var columnType = property.GetConfiguredColumnType();

                if (columnType != null)
                {
                    lines.Add(
                        $".{nameof(RelationalPropertyBuilderExtensions.HasColumnType)}" +
                        $"({this._code.Literal(columnType)})");
                }

                var maxLength = property.GetMaxLength();

                if (maxLength.HasValue)
                {
                    lines.Add(
                        $".{nameof(PropertyBuilder.HasMaxLength)}" +
                        $"({this._code.Literal(maxLength.Value)})");
                }
            }

            if (property.IsUnicode() != null)
            {
                lines.Add(
                    $".{nameof(PropertyBuilder.IsUnicode)}" +
                    $"({(property.IsUnicode() == false ? "false" : "")})");
            }

            if (property.IsFixedLength())
            {
                lines.Add(
                    $".{nameof(RelationalPropertyBuilderExtensions.IsFixedLength)}()");
            }

            if (property.GetDefaultValue() != null)
            {
                lines.Add(
                    $".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValue)}" +
                    $"({this._code.UnknownLiteral(property.GetDefaultValue())})");
            }

            if (property.GetDefaultValueSql() != null)
            {
                lines.Add(
                    $".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValueSql)}" +
                    $"({this._code.Literal(property.GetDefaultValueSql())})");
            }

            if (property.GetComment() != null)
            {
                lines.Add(
                    $".{nameof(RelationalPropertyBuilderExtensions.HasComment)}" +
                    $"({this._code.Literal(property.GetComment())})");
            }

            if (property.GetComputedColumnSql() != null)
            {
                lines.Add(
                    $".{nameof(RelationalPropertyBuilderExtensions.HasComputedColumnSql)}" +
                    $"({this._code.Literal(property.GetComputedColumnSql())})");
            }

            var valueGenerated = property.ValueGenerated;
            var isRowVersion   = false;

            if (((IConventionProperty)property).GetValueGeneratedConfigurationSource().HasValue &&
                RelationalValueGenerationConvention.GetValueGenerated(property) != valueGenerated)
            {
                string methodName;
                switch (valueGenerated)
                {
                case ValueGenerated.OnAdd:
                    methodName = nameof(PropertyBuilder.ValueGeneratedOnAdd);
                    break;

                case ValueGenerated.OnAddOrUpdate:
                    isRowVersion = property.IsConcurrencyToken;
                    methodName   = isRowVersion
                            ? nameof(PropertyBuilder.IsRowVersion)
                            : nameof(PropertyBuilder.ValueGeneratedOnAddOrUpdate);
                    break;

                case ValueGenerated.Never:
                    methodName = nameof(PropertyBuilder.ValueGeneratedNever);
                    break;

                default:
                    methodName = "";
                    break;
                }

                lines.Add($".{methodName}()");
            }

            if (property.IsConcurrencyToken &&
                !isRowVersion)
            {
                lines.Add($".{nameof(PropertyBuilder.IsConcurrencyToken)}()");
            }

            var annotationsToRemove = new List <IAnnotation>();

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

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

            switch (lines.Count)
            {
            case 1:
                return;

            case 2:
                lines = new List <string>
                {
                    lines[0] + lines[1]
                };
                break;
            }

            this.AppendMultiLineFluentApi(property.DeclaringEntityType, lines);
        }
Example #6
0
        private void GenerateProperty(IProperty property, bool useDataAnnotations)
        {
            var lines = new List <string> {
                $".{nameof(EntityTypeBuilder.Property)}({_code.Lambda(new [] { property.Name }, " e ")})"
            };

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

            _annotationCodeGenerator.RemoveAnnotationsHandledByConventions(property, annotations);
            annotations.Remove(ScaffoldingAnnotationNames.ColumnOrdinal);

            if (useDataAnnotations)
            {
                // Strip out any annotations handled as attributes - these are already handled when generating
                // the entity's properties
                // Only relational ones need to be removed here. Core ones are already removed by FilterIgnoredAnnotations
                annotations.Remove(RelationalAnnotationNames.ColumnName);
                annotations.Remove(RelationalAnnotationNames.ColumnType);

                _ = _annotationCodeGenerator.GenerateDataAnnotationAttributes(property, annotations);
            }
            else
            {
                if (!property.IsNullable &&
                    property.ClrType.IsNullableType() &&
                    !property.IsPrimaryKey())
                {
                    lines.Add($".{nameof(PropertyBuilder.IsRequired)}()");
                }

                var columnType = property.GetConfiguredColumnType();

                if (columnType != null)
                {
                    lines.Add(
                        $".{nameof(RelationalPropertyBuilderExtensions.HasColumnType)}" +
                        $"({_code.Literal(columnType)})");
                }

                var maxLength = property.GetMaxLength();

                if (maxLength.HasValue)
                {
                    lines.Add(
                        $".{nameof(PropertyBuilder.HasMaxLength)}" +
                        $"({_code.Literal(maxLength.Value)})");
                }
            }

            var precision = property.GetPrecision();
            var scale     = property.GetScale();

            if (precision != null && scale != null && scale != 0)
            {
                lines.Add(
                    $".{nameof(PropertyBuilder.HasPrecision)}" +
                    $"({_code.Literal(precision.Value)}, {_code.Literal(scale.Value)})");
            }
            else if (precision != null)
            {
                lines.Add(
                    $".{nameof(PropertyBuilder.HasPrecision)}" +
                    $"({_code.Literal(precision.Value)})");
            }

            if (property.IsUnicode() != null)
            {
                lines.Add(
                    $".{nameof(PropertyBuilder.IsUnicode)}" +
                    $"({(property.IsUnicode() == false ? "false" : "")})");
            }

            var defaultValue = property.GetDefaultValue();

            if (defaultValue == DBNull.Value)
            {
                lines.Add($".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValue)}()");
                annotations.Remove(RelationalAnnotationNames.DefaultValue);
            }
            else if (defaultValue != null)
            {
                lines.Add(
                    $".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValue)}" +
                    $"({_code.UnknownLiteral(defaultValue)})");
                annotations.Remove(RelationalAnnotationNames.DefaultValue);
            }

            var valueGenerated = property.ValueGenerated;
            var isRowVersion   = false;

            if (((IConventionProperty)property).GetValueGeneratedConfigurationSource() is ConfigurationSource valueGeneratedConfigurationSource &&
                valueGeneratedConfigurationSource != ConfigurationSource.Convention &&
                RelationalValueGenerationConvention.GetValueGenerated(property) != valueGenerated)
            {
                var methodName = valueGenerated switch
                {
                    ValueGenerated.OnAdd => nameof(PropertyBuilder.ValueGeneratedOnAdd),
                    ValueGenerated.OnAddOrUpdate => property.IsConcurrencyToken
                        ? nameof(PropertyBuilder.IsRowVersion)
                        : nameof(PropertyBuilder.ValueGeneratedOnAddOrUpdate),
                    ValueGenerated.OnUpdate => nameof(PropertyBuilder.ValueGeneratedOnUpdate),
                    ValueGenerated.Never => nameof(PropertyBuilder.ValueGeneratedNever),
                    _ => throw new InvalidOperationException(DesignStrings.UnhandledEnumValue($"{nameof(ValueGenerated)}.{valueGenerated}"))
                };

                lines.Add($".{methodName}()");
            }

            if (property.IsConcurrencyToken &&
                !isRowVersion)
            {
                lines.Add($".{nameof(PropertyBuilder.IsConcurrencyToken)}()");
            }

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

            switch (lines.Count)
            {
            case 1:
                return;

            case 2:
                lines = new List <string> {
                    lines[0] + lines[1]
                };
                break;
            }

            AppendMultiLineFluentApi(property.DeclaringEntityType, lines);
        }
Example #7
0
        private void GenerateProperty(IProperty property, bool useDataAnnotations)
        {
            var lines = new List <string> {
                $".{nameof(EntityTypeBuilder.Property)}(e => e.{property.Name})"
            };

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

            RemoveAnnotation(ref annotations, CoreAnnotationNames.MaxLength);
            RemoveAnnotation(ref annotations, CoreAnnotationNames.Precision);
            RemoveAnnotation(ref annotations, CoreAnnotationNames.Scale);
            RemoveAnnotation(ref annotations, CoreAnnotationNames.TypeMapping);
            RemoveAnnotation(ref annotations, CoreAnnotationNames.Unicode);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.ColumnName);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.ViewColumnName);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.ColumnType);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.DefaultValue);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.DefaultValueSql);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.Comment);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.ComputedColumnSql);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.IsFixedLength);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.TableColumnMappings);
            RemoveAnnotation(ref annotations, RelationalAnnotationNames.ViewColumnMappings);
            RemoveAnnotation(ref annotations, ScaffoldingAnnotationNames.ColumnOrdinal);

            if (!useDataAnnotations)
            {
                if (!property.IsNullable &&
                    property.ClrType.IsNullableType() &&
                    !property.IsPrimaryKey())
                {
                    lines.Add($".{nameof(PropertyBuilder.IsRequired)}()");
                }

                var columnName = property.GetColumnName();

                if (columnName != null &&
                    columnName != property.Name)
                {
                    lines.Add(
                        $".{nameof(RelationalPropertyBuilderExtensions.HasColumnName)}" +
                        $"({_code.Literal(columnName)})");
                }

                var viewColumnName = property.GetViewColumnName();

                if (viewColumnName != null &&
                    viewColumnName != columnName)
                {
                    lines.Add(
                        $".{nameof(RelationalPropertyBuilderExtensions.HasViewColumnName)}" +
                        $"({_code.Literal(columnName)})");
                }

                var columnType = property.GetConfiguredColumnType();

                if (columnType != null)
                {
                    lines.Add(
                        $".{nameof(RelationalPropertyBuilderExtensions.HasColumnType)}" +
                        $"({_code.Literal(columnType)})");
                }

                var maxLength = property.GetMaxLength();

                if (maxLength.HasValue)
                {
                    lines.Add(
                        $".{nameof(PropertyBuilder.HasMaxLength)}" +
                        $"({_code.Literal(maxLength.Value)})");
                }
            }

            var precision = property.GetPrecision();
            var scale     = property.GetScale();

            if (precision != null && scale != null && scale != 0)
            {
                lines.Add(
                    $".{nameof(PropertyBuilder.HasPrecision)}" +
                    $"({_code.Literal(precision.Value)}, {_code.Literal(scale.Value)})");
            }
            else if (precision != null)
            {
                lines.Add(
                    $".{nameof(PropertyBuilder.HasPrecision)}" +
                    $"({_code.Literal(precision.Value)})");
            }

            if (property.IsUnicode() != null)
            {
                lines.Add(
                    $".{nameof(PropertyBuilder.IsUnicode)}" +
                    $"({(property.IsUnicode() == false ? "false" : "")})");
            }

            if (property.IsFixedLength() != null)
            {
                lines.Add(
                    $".{nameof(RelationalPropertyBuilderExtensions.IsFixedLength)}()");
            }

            if (property.GetDefaultValue() != null)
            {
                lines.Add(
                    $".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValue)}" +
                    $"({_code.UnknownLiteral(property.GetDefaultValue())})");
            }

            if (property.GetDefaultValueSql() != null)
            {
                lines.Add(
                    $".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValueSql)}" +
                    $"({_code.Literal(property.GetDefaultValueSql())})");
            }

            if (property.GetComment() != null)
            {
                lines.Add(
                    $".{nameof(RelationalPropertyBuilderExtensions.HasComment)}" +
                    $"({_code.Literal(property.GetComment())})");
            }

            if (property.GetComputedColumnSql() != null)
            {
                lines.Add(
                    $".{nameof(RelationalPropertyBuilderExtensions.HasComputedColumnSql)}" +
                    $"({_code.Literal(property.GetComputedColumnSql())})");
            }

            var valueGenerated = property.ValueGenerated;
            var isRowVersion   = false;

            if (((IConventionProperty)property).GetValueGeneratedConfigurationSource().HasValue &&
                RelationalValueGenerationConvention.GetValueGenerated(property) != valueGenerated)
            {
                var methodName = valueGenerated switch
                {
                    ValueGenerated.OnAdd => nameof(PropertyBuilder.ValueGeneratedOnAdd),
                    ValueGenerated.OnAddOrUpdate => property.IsConcurrencyToken
                        ? nameof(PropertyBuilder.IsRowVersion)
                        : nameof(PropertyBuilder.ValueGeneratedOnAddOrUpdate),
                    ValueGenerated.OnUpdate => nameof(PropertyBuilder.ValueGeneratedOnUpdate),
                    ValueGenerated.Never => nameof(PropertyBuilder.ValueGeneratedNever),
                    _ => throw new InvalidOperationException(DesignStrings.UnhandledEnumValue($"{nameof(ValueGenerated)}.{valueGenerated}"))
                };

                lines.Add($".{methodName}()");
            }

            if (property.IsConcurrencyToken &&
                !isRowVersion)
            {
                lines.Add($".{nameof(PropertyBuilder.IsConcurrencyToken)}()");
            }

            var annotationsToRemove = new List <IAnnotation>();

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

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

            switch (lines.Count)
            {
            case 1:
                return;

            case 2:
                lines = new List <string> {
                    lines[0] + lines[1]
                };
                break;
            }

            AppendMultiLineFluentApi(property.DeclaringEntityType, lines);
        }
 protected override ValueGenerated?GetValueGenerated(IConventionProperty property)
 => RelationalValueGenerationConvention.GetValueGenerated(property)
 ?? (property.GetValueGenerationStrategy() != FbValueGenerationStrategy.None
                                 ? ValueGenerated.OnAdd
                                 : (ValueGenerated?)null);
Example #9
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 override ConventionSet CreateConventionSet()
        {
            var conventionSet = base.CreateConventionSet();

            var relationalColumnAttributeConvention  = new RelationalColumnAttributeConvention(Dependencies, RelationalDependencies);
            var relationalCommentAttributeConvention = new RelationalColumnCommentAttributeConvention(Dependencies, RelationalDependencies);

            conventionSet.PropertyAddedConventions.Add(relationalColumnAttributeConvention);
            conventionSet.PropertyAddedConventions.Add(relationalCommentAttributeConvention);

            var tableNameFromDbSetConvention = new TableNameFromDbSetConvention(Dependencies, RelationalDependencies);

            conventionSet.EntityTypeAddedConventions.Add(new RelationalTableAttributeConvention(Dependencies, RelationalDependencies));
            conventionSet.EntityTypeAddedConventions.Add(
                new RelationalTableCommentAttributeConvention(Dependencies, RelationalDependencies));
            conventionSet.EntityTypeAddedConventions.Add(tableNameFromDbSetConvention);

            ValueGenerationConvention valueGenerationConvention =
                new RelationalValueGenerationConvention(Dependencies, RelationalDependencies);

            ReplaceConvention(conventionSet.EntityTypeBaseTypeChangedConventions, valueGenerationConvention);
            conventionSet.EntityTypeBaseTypeChangedConventions.Add(tableNameFromDbSetConvention);

            conventionSet.EntityTypeAnnotationChangedConventions.Add((RelationalValueGenerationConvention)valueGenerationConvention);

            ReplaceConvention(conventionSet.EntityTypePrimaryKeyChangedConventions, valueGenerationConvention);

            ReplaceConvention(conventionSet.ForeignKeyAddedConventions, valueGenerationConvention);
            ReplaceConvention(conventionSet.ForeignKeyRemovedConventions, valueGenerationConvention);

            conventionSet.PropertyFieldChangedConventions.Add(relationalColumnAttributeConvention);
            conventionSet.PropertyFieldChangedConventions.Add(relationalCommentAttributeConvention);

            var storeGenerationConvention = new StoreGenerationConvention(Dependencies, RelationalDependencies);

            conventionSet.PropertyAnnotationChangedConventions.Add(storeGenerationConvention);
            conventionSet.PropertyAnnotationChangedConventions.Add((RelationalValueGenerationConvention)valueGenerationConvention);

            var dbFunctionAttributeConvention = new RelationalDbFunctionAttributeConvention(Dependencies, RelationalDependencies);

            conventionSet.ModelInitializedConventions.Add(dbFunctionAttributeConvention);

            // Use TypeMappingConvention to add the relational store type mapping
            // to the generated concurrency token property
            ConventionSet.AddBefore(
                conventionSet.ModelFinalizingConventions,
                new TableSharingConcurrencyTokenConvention(Dependencies, RelationalDependencies),
                typeof(TypeMappingConvention));
            // ModelCleanupConvention would remove the entity types added by TableValuedDbFunctionConvention #15898
            ConventionSet.AddAfter(
                conventionSet.ModelFinalizingConventions,
                new TableValuedDbFunctionConvention(Dependencies, RelationalDependencies),
                typeof(ModelCleanupConvention));
            conventionSet.ModelFinalizingConventions.Add(dbFunctionAttributeConvention);
            conventionSet.ModelFinalizingConventions.Add(tableNameFromDbSetConvention);
            conventionSet.ModelFinalizingConventions.Add(storeGenerationConvention);
            conventionSet.ModelFinalizingConventions.Add(new EntityTypeHierarchyMappingConvention(Dependencies, RelationalDependencies));
            conventionSet.ModelFinalizingConventions.Add(new SequenceUniquificationConvention(Dependencies, RelationalDependencies));
            conventionSet.ModelFinalizingConventions.Add(new SharedTableConvention(Dependencies, RelationalDependencies));
            conventionSet.ModelFinalizingConventions.Add(new DbFunctionTypeMappingConvention(Dependencies, RelationalDependencies));
            ReplaceConvention(
                conventionSet.ModelFinalizingConventions,
                (QueryFilterRewritingConvention) new RelationalQueryFilterRewritingConvention(
                    Dependencies, RelationalDependencies));

            ConventionSet.AddAfter(
                conventionSet.ModelFinalizedConventions,
                new RelationalModelConvention(Dependencies, RelationalDependencies),
                typeof(ValidatingConvention));

            return(conventionSet);
        }
Example #10
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());
        }
 public static new ValueGenerated?GetValueGenerated(IProperty property)
 => RelationalValueGenerationConvention.GetValueGenerated(property)
 ?? (property.GetValueGenerationStrategy() != FbValueGenerationStrategy.None
                                 ? ValueGenerated.OnAdd
                                 : (ValueGenerated?)null);
Example #12
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());
        }