-
-
Save AndrewPetz/c1a54e79ac54551d22a89fc8de4f51e3 to your computer and use it in GitHub Desktop.
DbContext.t4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<#@ 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" #> | |
<#@ template debug="true" #> | |
<# | |
System.Diagnostics.Debugger.Launch(); | |
#> | |
<# | |
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<IProviderConfigurationCodeGenerator>(); | |
var annotationCodeGenerator = services.GetRequiredService<IAnnotationCodeGenerator>(); | |
var code = services.GetRequiredService<ICSharpHelper>(); | |
var usings = new List<string> | |
{ | |
"System", | |
"System.Collections.Generic", | |
"Microsoft.AspNetCore.Identity", | |
"Microsoft.AspNetCore.Identity.EntityFrameworkCore", | |
"Microsoft.EntityFrameworkCore" | |
}; | |
var identityTablesList = new List<string> | |
{ | |
"Role", | |
"RoleClaim", | |
"User", | |
"UserClaim", | |
"UserLogin", | |
"UserRole", | |
"UserToken" | |
}; | |
if (NamespaceHint != Options.ModelNamespace | |
&& !string.IsNullOrEmpty(Options.ModelNamespace)) | |
{ | |
usings.Add(Options.ModelNamespace); | |
} | |
if (!string.IsNullOrEmpty(NamespaceHint)) | |
{ | |
#> | |
namespace <#= NamespaceHint #>; | |
<# | |
} | |
#> | |
public partial class <#= Options.ContextName #> : IdentityDbContext<User, Role, Guid> | |
{ | |
<# | |
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() && !identityTablesList.Contains(e.Name))) | |
{ | |
#> | |
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) | |
{ | |
base.OnModelCreating(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; | |
// handle my custom Identity stuff | |
#> | |
// Rename Identity tables to remove AspNet prefix and make singular | |
modelBuilder.Entity<User>(entity => | |
{ | |
entity.ToTable(name: "User"); | |
}); | |
modelBuilder.Entity<Role>(entity => | |
{ | |
entity.ToTable(name: "Role"); | |
}); | |
modelBuilder.Entity<IdentityUserRole<Guid>>(entity => | |
{ | |
entity.ToTable("UserRole"); | |
}); | |
modelBuilder.Entity<IdentityUserClaim<Guid>>(entity => | |
{ | |
entity.ToTable("UserClaim"); | |
}); | |
modelBuilder.Entity<IdentityUserLogin<Guid>>(entity => | |
{ | |
entity.ToTable("UserLogin"); | |
}); | |
modelBuilder.Entity<IdentityRoleClaim<Guid>>(entity => | |
{ | |
entity.ToTable("RoleClaim"); | |
}); | |
modelBuilder.Entity<IdentityUserToken<Guid>>(entity => | |
{ | |
entity.ToTable("UserToken"); | |
}); | |
<# | |
foreach (var entityType in Model.GetEntityTypes().Where(e => !e.IsSimpleManyToManyJoinEntityType() | |
&& !identityTablesList.Contains(e.Name))) | |
{ | |
// 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.Name #>)<#= 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<Dictionary<string, object>>( | |
<#= 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); | |
#> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment