<#@ template hostSpecific="true" #> <#@ assembly name="Microsoft.EntityFrameworkCore" #> <#@ assembly name="Microsoft.EntityFrameworkCore.Design" #> <#@ assembly name="Microsoft.EntityFrameworkCore.Relational" #> <#@ assembly name="Microsoft.Extensions.DependencyInjection.Abstractions" #> <#@ parameter name="Model" type="Microsoft.EntityFrameworkCore.Metadata.IModel" #> <#@ parameter name="Options" type="Microsoft.EntityFrameworkCore.Scaffolding.ModelCodeGenerationOptions" #> <#@ parameter name="NamespaceHint" type="System.String" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="Microsoft.EntityFrameworkCore" #> <#@ import namespace="Microsoft.EntityFrameworkCore.Design" #> <#@ import namespace="Microsoft.EntityFrameworkCore.Infrastructure" #> <#@ import namespace="Microsoft.EntityFrameworkCore.Scaffolding" #> <#@ import namespace="Microsoft.Extensions.DependencyInjection" #> <# if (!ProductInfo.GetVersion().StartsWith("8.0")) { Warning("Your templates were created using an older version of Entity Framework. Additional features and bug fixes may be available. See https://aka.ms/efcore-docs-updating-templates for more information."); } var services = (IServiceProvider)Host; var providerCode = services.GetRequiredService(); var annotationCodeGenerator = services.GetRequiredService(); var code = services.GetRequiredService(); var usings = new List { "System", "System.Collections.Generic", "Microsoft.EntityFrameworkCore" }; if (NamespaceHint != Options.ModelNamespace && !string.IsNullOrEmpty(Options.ModelNamespace)) { usings.Add(Options.ModelNamespace); } if (!string.IsNullOrEmpty(NamespaceHint)) { #> namespace <#= NamespaceHint #>; <# } #> public partial class <#= Options.ContextName #> : DbContext { <# if (!Options.SuppressOnConfiguring) { #> public <#= Options.ContextName #>() { } <# } #> public <#= Options.ContextName #>(DbContextOptions<<#= Options.ContextName #>> options) : base(options) { } <# foreach (var entityType in Model.GetEntityTypes().Where(e => !e.IsSimpleManyToManyJoinEntityType())) { #> public virtual DbSet<<#= entityType.Name #>> <#= entityType.GetDbSetName() #> { get; set; } <# } if (!Options.SuppressOnConfiguring) { #> protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) <# if (!Options.SuppressConnectionStringWarning) { #> #warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263. <# } var useProviderCall = providerCode.GenerateUseProvider(Options.ConnectionString); usings.AddRange(useProviderCall.GetRequiredUsings()); #> => optionsBuilder<#= code.Fragment(useProviderCall, indent: 3) #>; <# } #> protected override void OnModelCreating(ModelBuilder modelBuilder) { <# var anyConfiguration = false; var modelFluentApiCalls = Model.GetFluentApiCalls(annotationCodeGenerator); if (modelFluentApiCalls != null) { usings.AddRange(modelFluentApiCalls.GetRequiredUsings()); #> modelBuilder<#= code.Fragment(modelFluentApiCalls, indent: 3) #>; <# anyConfiguration = true; } StringBuilder mainEnvironment; foreach (var entityType in Model.GetEntityTypes().Where(e => !e.IsSimpleManyToManyJoinEntityType())) { // Save all previously generated code, and start generating into a new temporary environment mainEnvironment = GenerationEnvironment; GenerationEnvironment = new StringBuilder(); if (anyConfiguration) { WriteLine(""); } var anyEntityTypeConfiguration = false; #> modelBuilder.Entity<<#= entityType.Name #>>(entity => { <# var key = entityType.FindPrimaryKey(); if (key != null) { var keyFluentApiCalls = key.GetFluentApiCalls(annotationCodeGenerator); if (keyFluentApiCalls != null || (!key.IsHandledByConvention() && !Options.UseDataAnnotations)) { if (keyFluentApiCalls != null) { usings.AddRange(keyFluentApiCalls.GetRequiredUsings()); } #> entity.HasKey(<#= code.Lambda(key.Properties, "e") #>)<#= code.Fragment(keyFluentApiCalls, indent: 4) #>; <# anyEntityTypeConfiguration = true; } } var entityTypeFluentApiCalls = entityType.GetFluentApiCalls(annotationCodeGenerator) ?.FilterChain(c => !(Options.UseDataAnnotations && c.IsHandledByDataAnnotations)); if (entityTypeFluentApiCalls != null) { usings.AddRange(entityTypeFluentApiCalls.GetRequiredUsings()); if (anyEntityTypeConfiguration) { WriteLine(""); } #> entity<#= code.Fragment(entityTypeFluentApiCalls, indent: 4) #>; <# anyEntityTypeConfiguration = true; } foreach (var index in entityType.GetIndexes() .Where(i => !(Options.UseDataAnnotations && i.IsHandledByDataAnnotations(annotationCodeGenerator)))) { if (anyEntityTypeConfiguration) { WriteLine(""); } var indexFluentApiCalls = index.GetFluentApiCalls(annotationCodeGenerator); if (indexFluentApiCalls != null) { usings.AddRange(indexFluentApiCalls.GetRequiredUsings()); } #> entity.HasIndex(<#= code.Lambda(index.Properties, "e") #>, <#= code.Literal(index.GetDatabaseName()) #>)<#= code.Fragment(indexFluentApiCalls, indent: 4) #>; <# anyEntityTypeConfiguration = true; } var firstProperty = true; foreach (var property in entityType.GetProperties()) { var propertyFluentApiCalls = property.GetFluentApiCalls(annotationCodeGenerator) ?.FilterChain(c => !(Options.UseDataAnnotations && c.IsHandledByDataAnnotations) && !(c.Method == "IsRequired" && Options.UseNullableReferenceTypes && !property.ClrType.IsValueType)); if (propertyFluentApiCalls == null) { continue; } usings.AddRange(propertyFluentApiCalls.GetRequiredUsings()); if (anyEntityTypeConfiguration && firstProperty) { WriteLine(""); } #> entity.Property(e => e.<#= property.GetColumnName() #>)<#= code.Fragment(propertyFluentApiCalls, indent: 4) #>; <# anyEntityTypeConfiguration = true; firstProperty = false; } foreach (var foreignKey in entityType.GetForeignKeys()) { var foreignKeyFluentApiCalls = foreignKey.GetFluentApiCalls(annotationCodeGenerator) ?.FilterChain(c => !(Options.UseDataAnnotations && c.IsHandledByDataAnnotations)); if (foreignKeyFluentApiCalls == null) { continue; } usings.AddRange(foreignKeyFluentApiCalls.GetRequiredUsings()); if (anyEntityTypeConfiguration) { WriteLine(""); } #> entity.HasOne(d => d.<#= foreignKey.DependentToPrincipal.Name #>).<#= foreignKey.IsUnique ? "WithOne" : "WithMany" #>(<#= foreignKey.PrincipalToDependent != null ? $"p => p.{foreignKey.PrincipalToDependent.Name}" : "" #>)<#= code.Fragment(foreignKeyFluentApiCalls, indent: 4) #>; <# anyEntityTypeConfiguration = true; } foreach (var skipNavigation in entityType.GetSkipNavigations().Where(n => n.IsLeftNavigation())) { if (anyEntityTypeConfiguration) { WriteLine(""); } var left = skipNavigation.ForeignKey; var leftFluentApiCalls = left.GetFluentApiCalls(annotationCodeGenerator, useStrings: true); var right = skipNavigation.Inverse.ForeignKey; var rightFluentApiCalls = right.GetFluentApiCalls(annotationCodeGenerator, useStrings: true); var joinEntityType = skipNavigation.JoinEntityType; if (leftFluentApiCalls != null) { usings.AddRange(leftFluentApiCalls.GetRequiredUsings()); } if (rightFluentApiCalls != null) { usings.AddRange(rightFluentApiCalls.GetRequiredUsings()); } #> entity.HasMany(d => d.<#= skipNavigation.Name #>).WithMany(p => p.<#= skipNavigation.Inverse.Name #>) .UsingEntity>( <#= code.Literal(joinEntityType.Name) #>, r => r.HasOne<<#= right.PrincipalEntityType.Name #>>().WithMany()<#= code.Fragment(rightFluentApiCalls, indent: 6) #>, l => l.HasOne<<#= left.PrincipalEntityType.Name #>>().WithMany()<#= code.Fragment(leftFluentApiCalls, indent: 6) #>, j => { <# var joinKey = joinEntityType.FindPrimaryKey(); var joinKeyFluentApiCalls = joinKey.GetFluentApiCalls(annotationCodeGenerator); if (joinKeyFluentApiCalls != null) { usings.AddRange(joinKeyFluentApiCalls.GetRequiredUsings()); } #> j.HasKey(<#= code.Arguments(joinKey.Properties.Select(e => e.Name)) #>)<#= code.Fragment(joinKeyFluentApiCalls, indent: 7) #>; <# var joinEntityTypeFluentApiCalls = joinEntityType.GetFluentApiCalls(annotationCodeGenerator); if (joinEntityTypeFluentApiCalls != null) { usings.AddRange(joinEntityTypeFluentApiCalls.GetRequiredUsings()); #> j<#= code.Fragment(joinEntityTypeFluentApiCalls, indent: 7) #>; <# } foreach (var index in joinEntityType.GetIndexes()) { var indexFluentApiCalls = index.GetFluentApiCalls(annotationCodeGenerator); if (indexFluentApiCalls != null) { usings.AddRange(indexFluentApiCalls.GetRequiredUsings()); } #> j.HasIndex(<#= code.Literal(index.Properties.Select(e => e.Name).ToArray()) #>, <#= code.Literal(index.GetDatabaseName()) #>)<#= code.Fragment(indexFluentApiCalls, indent: 7) #>; <# } foreach (var property in joinEntityType.GetProperties()) { var propertyFluentApiCalls = property.GetFluentApiCalls(annotationCodeGenerator); if (propertyFluentApiCalls == null) { continue; } usings.AddRange(propertyFluentApiCalls.GetRequiredUsings()); #> j.IndexerProperty<<#= code.Reference(property.ClrType) #>>(<#= code.Literal(property.Name) #>)<#= code.Fragment(propertyFluentApiCalls, indent: 7) #>; <# } #> }); <# anyEntityTypeConfiguration = true; } #> }); <# // If any signicant code was generated, append it to the main environment if (anyEntityTypeConfiguration) { mainEnvironment.Append(GenerationEnvironment); anyConfiguration = true; } // Resume generating code into the main environment GenerationEnvironment = mainEnvironment; } foreach (var sequence in Model.GetSequences()) { var needsType = sequence.Type != typeof(long); var needsSchema = !string.IsNullOrEmpty(sequence.Schema) && sequence.Schema != sequence.Model.GetDefaultSchema(); var sequenceFluentApiCalls = sequence.GetFluentApiCalls(annotationCodeGenerator); #> modelBuilder.HasSequence<#= needsType ? $"<{code.Reference(sequence.Type)}>" : "" #>(<#= code.Literal(sequence.Name) #><#= needsSchema ? $", {code.Literal(sequence.Schema)}" : "" #>)<#= code.Fragment(sequenceFluentApiCalls, indent: 3) #>; <# } if (anyConfiguration) { WriteLine(""); } #> OnModelCreatingPartial(modelBuilder); } partial void OnModelCreatingPartial(ModelBuilder modelBuilder); } <# mainEnvironment = GenerationEnvironment; GenerationEnvironment = new StringBuilder(); foreach (var ns in usings.Distinct().OrderBy(x => x, new NamespaceComparer())) { #> using <#= ns #>; <# } WriteLine(""); GenerationEnvironment.Append(mainEnvironment); #>