/// <summary> /// Generate OnConfiguring method. /// </summary> /// <param name="connectionString">Database connection string.</param> /// <param name="suppressConnectionStringWarning">Suppress connection string warning.</param> protected virtual void GenerateOnConfiguring( string connectionString, bool suppressConnectionStringWarning) { if (connectionString == null) { throw new ArgumentNullException(nameof(connectionString)); } var sb = new IndentedStringBuilder(); using (sb.Indent()) { sb.IncrementIndent(); sb.AppendLine("protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)"); sb.AppendLine("{"); using (sb.Indent()) { sb.AppendLine("if (!optionsBuilder.IsConfigured)"); sb.AppendLine("{"); if (HandlebarsScaffoldingOptions.IncludeConnectionString) { using (sb.Indent()) { if (!suppressConnectionStringWarning) { sb.DecrementIndent() .DecrementIndent() .DecrementIndent() .DecrementIndent() .AppendLine("#warning " + DesignStrings.SensitiveInformationWarning) .IncrementIndent() .IncrementIndent() .IncrementIndent() .IncrementIndent(); } sb.Append("optionsBuilder") .Append( ProviderConfigurationCodeGenerator != null ? CSharpHelper.Fragment( ProviderConfigurationCodeGenerator.GenerateUseProvider(connectionString, null)) #pragma warning disable CS0618 // Type or member is obsolete : LegacyProviderCodeGenerator.GenerateUseProvider(connectionString, Language)) #pragma warning restore CS0618 // Type or member is obsolete .AppendLine(";"); } } sb.AppendLine("}"); } sb.AppendLine("}"); var onConfiguring = sb.ToString(); TemplateData.Add("on-configuring", onConfiguring); } }
/// <summary> /// Generate OnConfiguring method. /// </summary> /// <param name="connectionString">Database connection string.</param> /// <param name="suppressConnectionStringWarning">Suppress connection string warning.</param> protected override void GenerateOnConfiguring(string connectionString, bool suppressConnectionStringWarning) { Check.NotNull(connectionString, nameof(connectionString)); var sb = new IndentedStringBuilder(); using (sb.Indent()) using (sb.Indent()) { sb.AppendLine("protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)"); sb.AppendLine("{"); using (sb.Indent()) { sb.AppendLine("if (!optionsBuilder.IsConfigured)"); sb.AppendLine("{"); using (sb.Indent()) { if (!suppressConnectionStringWarning) { sb.DecrementIndent() .DecrementIndent() .DecrementIndent() .DecrementIndent() .AppendLine("#warning " + DesignStrings.SensitiveInformationWarning) .IncrementIndent() .IncrementIndent() .IncrementIndent() .IncrementIndent(); } sb.Append("optionsBuilder"); var useProviderCall = ProviderConfigurationCodeGenerator.GenerateUseProvider( connectionString, ProviderConfigurationCodeGenerator.GenerateProviderOptions()); var contextOptions = ProviderConfigurationCodeGenerator.GenerateContextOptions(); if (contextOptions != null) { useProviderCall = useProviderCall.Chain(contextOptions); } sb.Append(CSharpHelper.Fragment(useProviderCall)) .AppendLine(";"); } sb.AppendLine("}"); } sb.AppendLine("}"); } var onConfiguring = sb.ToString(); TemplateData.Add("on-configuring", onConfiguring); }
private void GenerateIndex(IIndex index, IndentedStringBuilder sb) { var lines = new List <string> { $".{nameof(EntityTypeBuilder.HasIndex)}(e => {GenerateLambdaToKey(index.Properties, "e")})" }; var annotations = index.GetAnnotations().ToList(); if (!string.IsNullOrEmpty((string)index[RelationalAnnotationNames.Name])) { lines.Add( $".{nameof(RelationalIndexBuilderExtensions.HasName)}" + $"({CSharpHelper.Literal(index.GetName())})"); RemoveAnnotation(ref annotations, RelationalAnnotationNames.Name); } if (index.IsUnique) { lines.Add($".{nameof(IndexBuilder.IsUnique)}()"); } if (index.GetFilter() != null) { lines.Add( $".{nameof(RelationalIndexBuilderExtensions.HasFilter)}" + $"({CSharpHelper.Literal(index.GetFilter())})"); RemoveAnnotation(ref annotations, RelationalAnnotationNames.Filter); } var annotationsToRemove = new List <IAnnotation>(); foreach (var annotation in annotations) { if (annotation.Value == null || AnnotationCodeGenerator.IsHandledByConvention(index, annotation)) { annotationsToRemove.Add(annotation); } else { var methodCall = AnnotationCodeGenerator.GenerateFluentApi(index, annotation); if (methodCall != null) { lines.Add(CSharpHelper.Fragment(methodCall)); annotationsToRemove.Add(annotation); } } } lines.AddRange(GenerateAnnotations(annotations.Except(annotationsToRemove))); AppendMultiLineFluentApi(index.DeclaringEntityType, lines, sb); }
private string GetOnConfiguring(string connectionString, bool suppressConnectionStringWarning) { var sb = new IndentedStringBuilder(); using (sb.Indent()) using (sb.Indent()) { sb.AppendLine("protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)"); sb.AppendLine("{"); using (sb.Indent()) { sb.AppendLine("if (!optionsBuilder.IsConfigured)"); sb.AppendLine("{"); using (sb.Indent()) { if (!suppressConnectionStringWarning) { sb.DecrementIndent() .DecrementIndent() .DecrementIndent() .DecrementIndent() .AppendLine("#warning " + DesignStrings.SensitiveInformationWarning) .IncrementIndent() .IncrementIndent() .IncrementIndent() .IncrementIndent(); } sb.Append("optionsBuilder"); var useProviderCall = ProviderConfigurationCodeGenerator.GenerateUseProvider(connectionString); sb.Append(CSharpHelper.Fragment(useProviderCall)) .AppendLine(";"); } sb.AppendLine("}"); } sb.AppendLine("}"); } return(sb.ToString()); }
/// <summary> /// Generate OnConfiguring method. /// </summary> /// <param name="connectionString">Database connection string.</param> /// <param name="suppressConnectionStringWarning">Suppress connection string warning.</param> protected override void GenerateOnConfiguring([NotNull] string connectionString, bool suppressConnectionStringWarning) { Check.NotNull(connectionString, nameof(connectionString)); var onConfiguring = GetOnConfiguring(connectionString, suppressConnectionStringWarning); TemplateData.Add("on-configuring", onConfiguring); TemplateData.Add("connection-string", connectionString); TemplateData.Add("connectionstring-warning", $"#warning {DesignStrings.SensitiveInformationWarning}"); var useProviderCall = ProviderConfigurationCodeGenerator.GenerateUseProvider( connectionString, ProviderConfigurationCodeGenerator.GenerateProviderOptions()); var contextOptions = ProviderConfigurationCodeGenerator.GenerateContextOptions(); if (contextOptions != null) { useProviderCall = useProviderCall.Chain(contextOptions); } TemplateData.Add("options-builder-provider", CSharpHelper.Fragment(useProviderCall)); }
private void GenerateRelationship(IForeignKey foreignKey, bool useDataAnnotations, IndentedStringBuilder sb) { var canUseDataAnnotations = true; var annotations = AnnotationCodeGenerator .FilterIgnoredAnnotations(foreignKey.GetAnnotations()) .ToDictionary(a => a.Name, a => a); AnnotationCodeGenerator.RemoveAnnotationsHandledByConventions(foreignKey, annotations); var lines = new List <string> { $".{nameof(EntityTypeBuilder.HasOne)}(" + (foreignKey.DependentToPrincipal != null ? $"d => d.{EntityTypeTransformationService.TransformNavPropertyName(foreignKey.DependentToPrincipal?.Name, foreignKey.PrincipalToDependent?.DeclaringType.Name)}" : null) + ")", $".{(foreignKey.IsUnique ? nameof(ReferenceNavigationBuilder.WithOne) : nameof(ReferenceNavigationBuilder.WithMany))}" + "(" + (foreignKey.PrincipalToDependent != null ? $"p => p.{EntityTypeTransformationService.TransformNavPropertyName(foreignKey.PrincipalToDependent?.Name, foreignKey.DependentToPrincipal?.DeclaringType.Name)}" : null) + ")" }; if (!foreignKey.PrincipalKey.IsPrimaryKey()) { canUseDataAnnotations = false; lines.Add( $".{nameof(ReferenceReferenceBuilder.HasPrincipalKey)}" + (foreignKey.IsUnique ? $"<{EntityTypeTransformationService.TransformPropertyName(((ITypeBase)foreignKey.PrincipalEntityType).DisplayName(), "")}>" : "") + $"(p => {GenerateLambdaToKey(foreignKey.PrincipalKey.Properties, "p", EntityTypeTransformationService.TransformNavPropertyName)})"); } lines.Add( $".{nameof(ReferenceReferenceBuilder.HasForeignKey)}" + (foreignKey.IsUnique ? $"<{GetEntityTypeName(foreignKey.PrincipalEntityType, EntityTypeTransformationService.TransformTypeEntityName(((ITypeBase)foreignKey.DeclaringEntityType).DisplayName()))}>" : "") + $"(d => {GenerateLambdaToKey(foreignKey.Properties, "d", EntityTypeTransformationService.TransformPropertyName)})"); var defaultOnDeleteAction = foreignKey.IsRequired ? DeleteBehavior.Cascade : DeleteBehavior.ClientSetNull; if (foreignKey.DeleteBehavior != defaultOnDeleteAction) { canUseDataAnnotations = false; lines.Add( $".{nameof(ReferenceReferenceBuilder.OnDelete)}({CSharpHelper.Literal(foreignKey.DeleteBehavior)})"); } if (!string.IsNullOrEmpty((string)foreignKey[RelationalAnnotationNames.Name])) { canUseDataAnnotations = false; } lines.AddRange( AnnotationCodeGenerator.GenerateFluentApiCalls(foreignKey, annotations).Select(m => CSharpHelper.Fragment(m)) .Concat(GenerateAnnotations(annotations.Values))); if (!useDataAnnotations || !canUseDataAnnotations) { AppendMultiLineFluentApi(foreignKey.DeclaringEntityType, lines, sb); } }
private void GenerateProperty(IProperty property, bool useDataAnnotations, IndentedStringBuilder sb) { var lines = new List <string> { $".{nameof(EntityTypeBuilder.Property)}(e => e.{EntityTypeTransformationService.TransformPropertyName(property.Name, property.DeclaringType.Name)})" }; 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)}({CSharpHelper.Literal(columnType)})"); annotations.Remove(RelationalAnnotationNames.ColumnType); } var maxLength = property.GetMaxLength(); if (maxLength.HasValue) { lines.Add( $".{nameof(PropertyBuilder.HasMaxLength)}({CSharpHelper.Literal(maxLength.Value)})"); } } var precision = property.GetPrecision(); var scale = property.GetScale(); if (precision != null && scale != null && scale != 0) { lines.Add( $".{nameof(PropertyBuilder.HasPrecision)}({CSharpHelper.Literal(precision.Value)}, {CSharpHelper.Literal(scale.Value)})"); } else if (precision != null) { lines.Add( $".{nameof(PropertyBuilder.HasPrecision)}({CSharpHelper.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)}({CSharpHelper.UnknownLiteral(defaultValue)})"); annotations.Remove(RelationalAnnotationNames.DefaultValue); } var valueGenerated = property.ValueGenerated; var isRowVersion = false; if (((IConventionProperty)property).GetValueGeneratedConfigurationSource() is ConfigurationSource valueGeneratedConfigurationSource && valueGeneratedConfigurationSource != ConfigurationSource.Convention && ValueGenerationConvention.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 => CSharpHelper.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, sb); }
private void GenerateIndex(IIndex index, IndentedStringBuilder sb) { var annotations = AnnotationCodeGenerator .FilterIgnoredAnnotations(index.GetAnnotations()) .ToDictionary(a => a.Name, a => a); AnnotationCodeGenerator.RemoveAnnotationsHandledByConventions(index, annotations); var lines = new List <string> { $".{nameof(EntityTypeBuilder.HasIndex)}(e => {GenerateLambdaToKey(index.Properties, "e", EntityTypeTransformationService.TransformPropertyName)})" }; annotations.Remove(RelationalAnnotationNames.Name); if (index.IsUnique) { lines.Add($".{nameof(IndexBuilder.IsUnique)}()"); } lines.AddRange( AnnotationCodeGenerator.GenerateFluentApiCalls(index, annotations).Select(m => CSharpHelper.Fragment(m)) .Concat(GenerateAnnotations(annotations.Values))); AppendMultiLineFluentApi(index.DeclaringEntityType, lines, sb); }
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); }
private void GenerateEntityType(IEntityType entityType, bool useDataAnnotations, IndentedStringBuilder sb) { GenerateKey(entityType.FindPrimaryKey(), entityType, useDataAnnotations, sb); var annotations = AnnotationCodeGenerator .FilterIgnoredAnnotations(entityType.GetAnnotations()) .ToDictionary(a => a.Name, a => a); AnnotationCodeGenerator.RemoveAnnotationsHandledByConventions(entityType, annotations); annotations.Remove(RelationalAnnotationNames.TableName); annotations.Remove(RelationalAnnotationNames.Schema); annotations.Remove(RelationalAnnotationNames.ViewName); annotations.Remove(RelationalAnnotationNames.ViewSchema); annotations.Remove(ScaffoldingAnnotationNames.DbSetName); annotations.Remove(RelationalAnnotationNames.ViewDefinitionSql); if (useDataAnnotations) { // Strip out any annotations handled as attributes - these are already handled when generating // the entity's properties _ = AnnotationCodeGenerator.GenerateDataAnnotationAttributes(entityType, annotations); } if (!useDataAnnotations || entityType.GetViewName() != null) { GenerateTableName(entityType, sb); } var lines = new List <string>( AnnotationCodeGenerator.GenerateFluentApiCalls(entityType, annotations).Select(m => CSharpHelper.Fragment(m)) .Concat(GenerateAnnotations(annotations.Values))); AppendMultiLineFluentApi(entityType, lines, sb); foreach (var index in entityType.GetIndexes()) { // If there are annotations that cannot be represented using an IndexAttribute then use fluent API even // if useDataAnnotations is true. var indexAnnotations = AnnotationCodeGenerator .FilterIgnoredAnnotations(index.GetAnnotations()) .ToDictionary(a => a.Name, a => a); AnnotationCodeGenerator.RemoveAnnotationsHandledByConventions(index, indexAnnotations); if (!useDataAnnotations || indexAnnotations.Count > 0) { GenerateIndex(index, sb); } } foreach (var property in entityType.GetProperties()) { GenerateProperty(property, useDataAnnotations, sb); } foreach (var foreignKey in entityType.GetScaffoldForeignKeys(_options.Value)) { GenerateRelationship(foreignKey, useDataAnnotations, sb); } }
/// <summary> /// Generate OnModelBuilding method. /// </summary> /// <param name="model">Metadata about the shape of entities, the relationships between them, and how they map to the database.</param> /// <param name="useDataAnnotations">Use fluent modeling API if false.</param> protected override void GenerateOnModelCreating([NotNull] IModel model, bool useDataAnnotations) { Check.NotNull(model, nameof(model)); var sb = new IndentedStringBuilder(); using (sb.Indent()) using (sb.Indent()) { sb.AppendLine("protected override void OnModelCreating(ModelBuilder modelBuilder)"); sb.Append("{"); var annotations = AnnotationCodeGenerator .FilterIgnoredAnnotations(model.GetAnnotations()) .ToDictionary(a => a.Name, a => a); AnnotationCodeGenerator.RemoveAnnotationsHandledByConventions(model, annotations); annotations.Remove(CoreAnnotationNames.ProductVersion); annotations.Remove(RelationalAnnotationNames.MaxIdentifierLength); annotations.Remove(ScaffoldingAnnotationNames.DatabaseName); annotations.Remove(ScaffoldingAnnotationNames.EntityTypeErrors); var lines = new List <string>(); lines.AddRange( AnnotationCodeGenerator.GenerateFluentApiCalls(model, annotations).Select(m => CSharpHelper.Fragment(m)) .Concat(GenerateAnnotations(annotations.Values))); if (lines.Count > 0) { using (sb.Indent()) { sb.AppendLine(); sb.Append("modelBuilder" + lines[0]); using (sb.Indent()) { foreach (var line in lines.Skip(1)) { sb.AppendLine(); sb.Append(line); } } sb.AppendLine(";"); } } using (sb.Indent()) { foreach (var entityType in model.GetScaffoldEntityTypes(_options.Value)) { _entityTypeBuilderInitialized = false; GenerateEntityType(entityType, useDataAnnotations, sb); if (_entityTypeBuilderInitialized) { sb.AppendLine("});"); } } foreach (var sequence in model.GetSequences()) { GenerateSequence(sequence, sb); } } sb.AppendLine(); using (sb.Indent()) { sb.AppendLine("OnModelCreatingPartial(modelBuilder);"); } sb.AppendLine("}"); sb.AppendLine(); sb.Append("partial void OnModelCreatingPartial(ModelBuilder modelBuilder);"); } var onModelCreating = sb.ToString(); TemplateData.Add("on-model-creating", onModelCreating); }
private void GenerateRelationship(IForeignKey foreignKey, bool useDataAnnotations, IndentedStringBuilder sb) { var canUseDataAnnotations = true; var annotations = foreignKey.GetAnnotations().ToList(); var lines = new List <string> { $".{nameof(EntityTypeBuilder.HasOne)}(" + (foreignKey.DependentToPrincipal != null ? $"d => d.{foreignKey.DependentToPrincipal.Name}" : null) + ")", $".{(foreignKey.IsUnique ? nameof(ReferenceNavigationBuilder.WithOne) : nameof(ReferenceNavigationBuilder.WithMany))}" + $"(" + (foreignKey.PrincipalToDependent != null ? $"p => p.{foreignKey.PrincipalToDependent.Name}" : null) + ")" }; if (!foreignKey.PrincipalKey.IsPrimaryKey()) { canUseDataAnnotations = false; lines.Add( $".{nameof(ReferenceReferenceBuilder.HasPrincipalKey)}" + (foreignKey.IsUnique ? $"<{((ITypeBase)foreignKey.PrincipalEntityType).DisplayName()}>" : "") + $"(p => {GenerateLambdaToKey(foreignKey.PrincipalKey.Properties, "p")})"); } lines.Add( $".{nameof(ReferenceReferenceBuilder.HasForeignKey)}" + (foreignKey.IsUnique ? $"<{((ITypeBase)foreignKey.DeclaringEntityType).DisplayName()}>" : "") + $"(d => {GenerateLambdaToKey(foreignKey.Properties, "d")})"); var defaultOnDeleteAction = foreignKey.IsRequired ? DeleteBehavior.Cascade : DeleteBehavior.ClientSetNull; if (foreignKey.DeleteBehavior != defaultOnDeleteAction) { canUseDataAnnotations = false; lines.Add( $".{nameof(ReferenceReferenceBuilder.OnDelete)}" + $"({CSharpHelper.Literal(foreignKey.DeleteBehavior)})"); } if (!string.IsNullOrEmpty((string)foreignKey[RelationalAnnotationNames.Name])) { canUseDataAnnotations = false; lines.Add( $".HasConstraintName" + $"({CSharpHelper.Literal(foreignKey.GetConstraintName())})"); RemoveAnnotation(ref annotations, RelationalAnnotationNames.Name); } var annotationsToRemove = new List <IAnnotation>(); foreach (var annotation in annotations) { if (annotation.Value == null || AnnotationCodeGenerator.IsHandledByConvention(foreignKey, annotation)) { annotationsToRemove.Add(annotation); } else { var methodCall = AnnotationCodeGenerator.GenerateFluentApi(foreignKey, annotation); if (methodCall != null) { canUseDataAnnotations = false; lines.Add(CSharpHelper.Fragment(methodCall)); annotationsToRemove.Add(annotation); } } } lines.AddRange(GenerateAnnotations(annotations.Except(annotationsToRemove))); if (!useDataAnnotations || !canUseDataAnnotations) { AppendMultiLineFluentApi(foreignKey.DeclaringEntityType, lines, sb); } }
private void GenerateProperty(IProperty property, bool useDataAnnotations, IndentedStringBuilder sb) { var lines = new List <string> { $".{nameof(EntityTypeBuilder.Property)}(e => e.{property.Name})" }; 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)}" + $"({CSharpHelper.Literal(columnName)})"); } var columnType = property.GetConfiguredColumnType(); if (columnType != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasColumnType)}" + $"({CSharpHelper.Literal(columnType)})"); } var maxLength = property.GetMaxLength(); if (maxLength.HasValue) { lines.Add( $".{nameof(PropertyBuilder.HasMaxLength)}" + $"({CSharpHelper.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)}" + $"({CSharpHelper.UnknownLiteral(property.GetDefaultValue())})"); } if (property.GetDefaultValueSql() != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValueSql)}" + $"({CSharpHelper.Literal(property.GetDefaultValueSql())})"); } if (property.GetComment() != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasComment)}" + $"({CSharpHelper.Literal(property.GetComment())})"); } if (property.GetComputedColumnSql() != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasComputedColumnSql)}" + $"({CSharpHelper.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 || AnnotationCodeGenerator.IsHandledByConvention(property, annotation)) { annotationsToRemove.Add(annotation); } else { var methodCall = AnnotationCodeGenerator.GenerateFluentApi(property, annotation); if (methodCall != null) { lines.Add(CSharpHelper.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, sb); }
private void GenerateKey(IKey key, IEntityType entityType, bool useDataAnnotations, IndentedStringBuilder sb) { if (key == null) { var line = new List <string> { $".{nameof(EntityTypeBuilder.HasNoKey)}()" }; AppendMultiLineFluentApi(entityType, line, sb); 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)}" + $"({CSharpHelper.Literal(key.GetName())})"); } var annotationsToRemove = new List <IAnnotation>(); foreach (var annotation in annotations) { if (annotation.Value == null || AnnotationCodeGenerator.IsHandledByConvention(key, annotation)) { annotationsToRemove.Add(annotation); } else { var methodCall = AnnotationCodeGenerator.GenerateFluentApi(key, annotation); if (methodCall != null) { lines.Add(CSharpHelper.Fragment(methodCall)); annotationsToRemove.Add(annotation); } } } lines.AddRange(GenerateAnnotations(annotations.Except(annotationsToRemove))); AppendMultiLineFluentApi(key.DeclaringEntityType, lines, sb); }
private void GenerateEntityType(IEntityType entityType, bool useDataAnnotations, IndentedStringBuilder sb) { GenerateKey(entityType.FindPrimaryKey(), entityType, useDataAnnotations, sb); var annotations = entityType.GetAnnotations().ToList(); RemoveAnnotation(ref annotations, CoreAnnotationNames.ConstructorBinding); RemoveAnnotation(ref annotations, RelationalAnnotationNames.TableName); RemoveAnnotation(ref annotations, RelationalAnnotationNames.Comment); RemoveAnnotation(ref annotations, RelationalAnnotationNames.Schema); RemoveAnnotation(ref annotations, ScaffoldingAnnotationNames.DbSetName); RemoveAnnotation(ref annotations, RelationalAnnotationNames2.ViewDefinition); var isView = entityType.FindAnnotation(RelationalAnnotationNames2.ViewDefinition) != null; if (!useDataAnnotations || isView) { GenerateTableName(entityType, sb); } var annotationsToRemove = new List <IAnnotation>(); var lines = new List <string>(); foreach (var annotation in annotations) { if (annotation.Value == null || AnnotationCodeGenerator.IsHandledByConvention(entityType, annotation)) { annotationsToRemove.Add(annotation); } else { var methodCall = AnnotationCodeGenerator.GenerateFluentApi(entityType, annotation); if (methodCall != null) { lines.Add(CSharpHelper.Fragment(methodCall)); annotationsToRemove.Add(annotation); } } } lines.AddRange(GenerateAnnotations(annotations.Except(annotationsToRemove))); if (entityType.GetComment() != null) { lines.Add( $".{nameof(RelationalEntityTypeBuilderExtensions.HasComment)}" + $"({CSharpHelper.Literal(entityType.GetComment())})"); } AppendMultiLineFluentApi(entityType, lines, sb); foreach (var index in entityType.GetIndexes()) { GenerateIndex(index, sb); } foreach (var property in entityType.GetProperties()) { GenerateProperty(property, useDataAnnotations, sb); } foreach (var foreignKey in entityType.GetScaffoldForeignKeys(_options.Value)) { GenerateRelationship(foreignKey, useDataAnnotations, sb); } }
/// <summary> /// Generate OnModelBuilding method. /// </summary> /// <param name="model">Metadata about the shape of entities, the relationships between them, and how they map to the database.</param> /// <param name="useDataAnnotations">Use fluent modeling API if false.</param> protected override void GenerateOnModelCreating(IModel model, bool useDataAnnotations) { Check.NotNull(model, nameof(model)); var sb = new IndentedStringBuilder(); using (sb.Indent()) using (sb.Indent()) { sb.AppendLine("protected override void OnModelCreating(ModelBuilder modelBuilder)"); sb.Append("{"); var annotations = model.GetAnnotations().ToList(); RemoveAnnotation(ref annotations, CoreAnnotationNames.ProductVersion); RemoveAnnotation(ref annotations, CoreAnnotationNames.ChangeTrackingStrategy); RemoveAnnotation(ref annotations, CoreAnnotationNames.OwnedTypes); RemoveAnnotation(ref annotations, ChangeDetector.SkipDetectChangesAnnotation); RemoveAnnotation(ref annotations, RelationalAnnotationNames.MaxIdentifierLength); RemoveAnnotation(ref annotations, RelationalAnnotationNames.CheckConstraints); RemoveAnnotation(ref annotations, ScaffoldingAnnotationNames.DatabaseName); RemoveAnnotation(ref annotations, ScaffoldingAnnotationNames.EntityTypeErrors); var annotationsToRemove = new List <IAnnotation>(); annotationsToRemove.AddRange( annotations.Where( a => a.Name.StartsWith(RelationalAnnotationNames.SequencePrefix, StringComparison.Ordinal))); var lines = new List <string>(); foreach (var annotation in annotations) { if (annotation.Value == null || AnnotationCodeGenerator.IsHandledByConvention(model, annotation)) { annotationsToRemove.Add(annotation); } else { var methodCall = AnnotationCodeGenerator.GenerateFluentApi(model, annotation); if (methodCall != null) { lines.Add(CSharpHelper.Fragment(methodCall)); annotationsToRemove.Add(annotation); } } } lines.AddRange(GenerateAnnotations(annotations.Except(annotationsToRemove))); if (lines.Count > 0) { using (sb.Indent()) { sb.AppendLine(); sb.Append("modelBuilder" + lines[0]); using (sb.Indent()) { foreach (var line in lines.Skip(1)) { sb.AppendLine(); sb.Append(line); } } sb.AppendLine(";"); } } using (sb.Indent()) { foreach (var entityType in model.GetScaffoldEntityTypes(_options.Value)) { _entityTypeBuilderInitialized = false; GenerateEntityType(entityType, useDataAnnotations, sb); if (_entityTypeBuilderInitialized) { sb.AppendLine("});"); } } foreach (var sequence in model.GetSequences()) { GenerateSequence(sequence, sb); } } sb.AppendLine(); using (sb.Indent()) { sb.AppendLine("OnModelCreatingPartial(modelBuilder);"); } sb.AppendLine("}"); sb.AppendLine(); sb.Append("partial void OnModelCreatingPartial(ModelBuilder modelBuilder);"); } var onModelCreating = sb.ToString(); TemplateData.Add("on-model-creating", onModelCreating); }