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