Last active
March 6, 2024 09:53
-
-
Save gistlyn/f59b78480869397546361515aa34f790 to your computer and use it in GitHub Desktop.
ef-postgres
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
dotnet add package ServiceStack.OrmLite.PostgreSQL | |
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL |
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
using Microsoft.EntityFrameworkCore; | |
using ServiceStack.Data; | |
using ServiceStack.OrmLite; | |
using MyApp.Data; | |
[assembly: HostingStartup(typeof(MyApp.ConfigureDb))] | |
namespace MyApp; | |
public class ConfigureDb : IHostingStartup | |
{ | |
public void Configure(IWebHostBuilder builder) => builder | |
.ConfigureServices((context, services) => { | |
var connectionString = context.Configuration.GetConnectionString("DefaultConnection") | |
?? "Server=localhost;User Id=test;Password=test;Database=test;Pooling=true;MinPoolSize=0;MaxPoolSize=200"; | |
services.AddSingleton<IDbConnectionFactory>(new OrmLiteConnectionFactory( | |
connectionString, PostgreSqlDialect.Provider)); | |
// $ dotnet ef migrations add CreateIdentitySchema | |
// $ dotnet ef database update | |
services.AddDbContext<ApplicationDbContext>(options => | |
options.UseNpgsql(connectionString, b => b.MigrationsAssembly(nameof(MyApp)))); | |
// Enable built-in Database Admin UI at /admin-ui/database | |
services.AddPlugin(new AdminDatabaseFeature()); | |
}); | |
} |
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
using Microsoft.AspNetCore.Identity; | |
using Microsoft.EntityFrameworkCore; | |
using MyApp.Data; | |
using MyApp.Migrations; | |
using MyApp.ServiceModel; | |
using ServiceStack; | |
using ServiceStack.Data; | |
using ServiceStack.OrmLite; | |
[assembly: HostingStartup(typeof(MyApp.ConfigureDbMigrations))] | |
namespace MyApp; | |
// Code-First DB Migrations: https://docs.servicestack.net/ormlite/db-migrations | |
public class ConfigureDbMigrations : IHostingStartup | |
{ | |
public void Configure(IWebHostBuilder builder) => builder | |
.ConfigureAppHost(appHost => { | |
var migrator = new Migrator(appHost.Resolve<IDbConnectionFactory>(), typeof(Migration1000).Assembly); | |
AppTasks.Register("migrate", _ => | |
{ | |
var log = appHost.GetApplicationServices().GetRequiredService<ILogger<ConfigureDbMigrations>>(); | |
log.LogInformation("Running EF Migrations..."); | |
var scopeFactory = appHost.GetApplicationServices().GetRequiredService<IServiceScopeFactory>(); | |
using (var scope = scopeFactory.CreateScope()) | |
{ | |
using var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>(); | |
db.Database.EnsureCreated(); | |
db.Database.Migrate(); | |
// Only seed users if DB was just created | |
if (!db.Users.Any()) | |
{ | |
log.LogInformation("Adding Seed Users..."); | |
AddSeedUsers(scope.ServiceProvider).Wait(); | |
} | |
} | |
log.LogInformation("Running OrmLite Migrations..."); | |
migrator.Run(); | |
}); | |
AppTasks.Register("migrate.revert", args => migrator.Revert(args[0])); | |
AppTasks.Run(); | |
}); | |
private async Task AddSeedUsers(IServiceProvider services) | |
{ | |
//initializing custom roles | |
var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>(); | |
var userManager = services.GetRequiredService<UserManager<ApplicationUser>>(); | |
string[] allRoles = [Roles.Admin, Roles.Manager, Roles.Employee]; | |
void assertResult(IdentityResult result) | |
{ | |
if (!result.Succeeded) | |
throw new Exception(result.Errors.First().Description); | |
} | |
async Task EnsureUserAsync(ApplicationUser user, string password, string[]? roles = null) | |
{ | |
var existingUser = await userManager.FindByEmailAsync(user.Email!); | |
if (existingUser != null) return; | |
await userManager!.CreateAsync(user, password); | |
if (roles?.Length > 0) | |
{ | |
var newUser = await userManager.FindByEmailAsync(user.Email!); | |
assertResult(await userManager.AddToRolesAsync(user, roles)); | |
} | |
} | |
foreach (var roleName in allRoles) | |
{ | |
var roleExist = await roleManager.RoleExistsAsync(roleName); | |
if (!roleExist) | |
{ | |
//Create the roles and seed them to the database | |
assertResult(await roleManager.CreateAsync(new IdentityRole(roleName))); | |
} | |
} | |
await EnsureUserAsync(new ApplicationUser | |
{ | |
DisplayName = "Test User", | |
Email = "test@email.com", | |
UserName = "test@email.com", | |
FirstName = "Test", | |
LastName = "User", | |
EmailConfirmed = true, | |
ProfileUrl = "/img/profiles/user1.svg", | |
}, "p@55wOrd"); | |
await EnsureUserAsync(new ApplicationUser | |
{ | |
DisplayName = "Test Employee", | |
Email = "employee@email.com", | |
UserName = "employee@email.com", | |
FirstName = "Test", | |
LastName = "Employee", | |
EmailConfirmed = true, | |
ProfileUrl = "/img/profiles/user2.svg", | |
}, "p@55wOrd", [Roles.Employee]); | |
await EnsureUserAsync(new ApplicationUser | |
{ | |
DisplayName = "Test Manager", | |
Email = "manager@email.com", | |
UserName = "manager@email.com", | |
FirstName = "Test", | |
LastName = "Manager", | |
EmailConfirmed = true, | |
ProfileUrl = "/img/profiles/user3.svg", | |
}, "p@55wOrd", [Roles.Manager, Roles.Employee]); | |
await EnsureUserAsync(new ApplicationUser | |
{ | |
DisplayName = "Admin User", | |
Email = "admin@email.com", | |
UserName = "admin@email.com", | |
FirstName = "Admin", | |
LastName = "User", | |
EmailConfirmed = true, | |
}, "p@55wOrd", allRoles); | |
} | |
} |
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
using System; | |
using Microsoft.EntityFrameworkCore.Migrations; | |
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; | |
#nullable disable | |
namespace MyApp.Migrations | |
{ | |
/// <inheritdoc /> | |
public partial class CreateIdentitySchema : Migration | |
{ | |
/// <inheritdoc /> | |
protected override void Up(MigrationBuilder migrationBuilder) | |
{ | |
migrationBuilder.CreateTable( | |
name: "AspNetRoles", | |
columns: table => new | |
{ | |
Id = table.Column<string>(type: "text", nullable: false), | |
Name = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), | |
NormalizedName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), | |
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true) | |
}, | |
constraints: table => | |
{ | |
table.PrimaryKey("PK_AspNetRoles", x => x.Id); | |
}); | |
migrationBuilder.CreateTable( | |
name: "AspNetUsers", | |
columns: table => new | |
{ | |
Id = table.Column<string>(type: "text", nullable: false), | |
FirstName = table.Column<string>(type: "text", nullable: true), | |
LastName = table.Column<string>(type: "text", nullable: true), | |
DisplayName = table.Column<string>(type: "text", nullable: true), | |
ProfileUrl = table.Column<string>(type: "text", nullable: true), | |
UserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), | |
NormalizedUserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), | |
Email = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), | |
NormalizedEmail = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), | |
EmailConfirmed = table.Column<bool>(type: "boolean", nullable: false), | |
PasswordHash = table.Column<string>(type: "text", nullable: true), | |
SecurityStamp = table.Column<string>(type: "text", nullable: true), | |
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true), | |
PhoneNumber = table.Column<string>(type: "text", nullable: true), | |
PhoneNumberConfirmed = table.Column<bool>(type: "boolean", nullable: false), | |
TwoFactorEnabled = table.Column<bool>(type: "boolean", nullable: false), | |
LockoutEnd = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true), | |
LockoutEnabled = table.Column<bool>(type: "boolean", nullable: false), | |
AccessFailedCount = table.Column<int>(type: "integer", nullable: false) | |
}, | |
constraints: table => | |
{ | |
table.PrimaryKey("PK_AspNetUsers", x => x.Id); | |
}); | |
migrationBuilder.CreateTable( | |
name: "AspNetRoleClaims", | |
columns: table => new | |
{ | |
Id = table.Column<int>(type: "integer", nullable: false) | |
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), | |
RoleId = table.Column<string>(type: "text", nullable: false), | |
ClaimType = table.Column<string>(type: "text", nullable: true), | |
ClaimValue = table.Column<string>(type: "text", nullable: true) | |
}, | |
constraints: table => | |
{ | |
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); | |
table.ForeignKey( | |
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", | |
column: x => x.RoleId, | |
principalTable: "AspNetRoles", | |
principalColumn: "Id", | |
onDelete: ReferentialAction.Cascade); | |
}); | |
migrationBuilder.CreateTable( | |
name: "AspNetUserClaims", | |
columns: table => new | |
{ | |
Id = table.Column<int>(type: "integer", nullable: false) | |
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), | |
UserId = table.Column<string>(type: "text", nullable: false), | |
ClaimType = table.Column<string>(type: "text", nullable: true), | |
ClaimValue = table.Column<string>(type: "text", nullable: true) | |
}, | |
constraints: table => | |
{ | |
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); | |
table.ForeignKey( | |
name: "FK_AspNetUserClaims_AspNetUsers_UserId", | |
column: x => x.UserId, | |
principalTable: "AspNetUsers", | |
principalColumn: "Id", | |
onDelete: ReferentialAction.Cascade); | |
}); | |
migrationBuilder.CreateTable( | |
name: "AspNetUserLogins", | |
columns: table => new | |
{ | |
LoginProvider = table.Column<string>(type: "text", nullable: false), | |
ProviderKey = table.Column<string>(type: "text", nullable: false), | |
ProviderDisplayName = table.Column<string>(type: "text", nullable: true), | |
UserId = table.Column<string>(type: "text", nullable: false) | |
}, | |
constraints: table => | |
{ | |
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); | |
table.ForeignKey( | |
name: "FK_AspNetUserLogins_AspNetUsers_UserId", | |
column: x => x.UserId, | |
principalTable: "AspNetUsers", | |
principalColumn: "Id", | |
onDelete: ReferentialAction.Cascade); | |
}); | |
migrationBuilder.CreateTable( | |
name: "AspNetUserRoles", | |
columns: table => new | |
{ | |
UserId = table.Column<string>(type: "text", nullable: false), | |
RoleId = table.Column<string>(type: "text", nullable: false) | |
}, | |
constraints: table => | |
{ | |
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); | |
table.ForeignKey( | |
name: "FK_AspNetUserRoles_AspNetRoles_RoleId", | |
column: x => x.RoleId, | |
principalTable: "AspNetRoles", | |
principalColumn: "Id", | |
onDelete: ReferentialAction.Cascade); | |
table.ForeignKey( | |
name: "FK_AspNetUserRoles_AspNetUsers_UserId", | |
column: x => x.UserId, | |
principalTable: "AspNetUsers", | |
principalColumn: "Id", | |
onDelete: ReferentialAction.Cascade); | |
}); | |
migrationBuilder.CreateTable( | |
name: "AspNetUserTokens", | |
columns: table => new | |
{ | |
UserId = table.Column<string>(type: "text", nullable: false), | |
LoginProvider = table.Column<string>(type: "text", nullable: false), | |
Name = table.Column<string>(type: "text", nullable: false), | |
Value = table.Column<string>(type: "text", nullable: true) | |
}, | |
constraints: table => | |
{ | |
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); | |
table.ForeignKey( | |
name: "FK_AspNetUserTokens_AspNetUsers_UserId", | |
column: x => x.UserId, | |
principalTable: "AspNetUsers", | |
principalColumn: "Id", | |
onDelete: ReferentialAction.Cascade); | |
}); | |
migrationBuilder.CreateIndex( | |
name: "IX_AspNetRoleClaims_RoleId", | |
table: "AspNetRoleClaims", | |
column: "RoleId"); | |
migrationBuilder.CreateIndex( | |
name: "RoleNameIndex", | |
table: "AspNetRoles", | |
column: "NormalizedName", | |
unique: true); | |
migrationBuilder.CreateIndex( | |
name: "IX_AspNetUserClaims_UserId", | |
table: "AspNetUserClaims", | |
column: "UserId"); | |
migrationBuilder.CreateIndex( | |
name: "IX_AspNetUserLogins_UserId", | |
table: "AspNetUserLogins", | |
column: "UserId"); | |
migrationBuilder.CreateIndex( | |
name: "IX_AspNetUserRoles_RoleId", | |
table: "AspNetUserRoles", | |
column: "RoleId"); | |
migrationBuilder.CreateIndex( | |
name: "EmailIndex", | |
table: "AspNetUsers", | |
column: "NormalizedEmail"); | |
migrationBuilder.CreateIndex( | |
name: "UserNameIndex", | |
table: "AspNetUsers", | |
column: "NormalizedUserName", | |
unique: true); | |
} | |
/// <inheritdoc /> | |
protected override void Down(MigrationBuilder migrationBuilder) | |
{ | |
migrationBuilder.DropTable( | |
name: "AspNetRoleClaims"); | |
migrationBuilder.DropTable( | |
name: "AspNetUserClaims"); | |
migrationBuilder.DropTable( | |
name: "AspNetUserLogins"); | |
migrationBuilder.DropTable( | |
name: "AspNetUserRoles"); | |
migrationBuilder.DropTable( | |
name: "AspNetUserTokens"); | |
migrationBuilder.DropTable( | |
name: "AspNetRoles"); | |
migrationBuilder.DropTable( | |
name: "AspNetUsers"); | |
} | |
} | |
} |
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
// <auto-generated /> | |
using System; | |
using Microsoft.EntityFrameworkCore; | |
using Microsoft.EntityFrameworkCore.Infrastructure; | |
using Microsoft.EntityFrameworkCore.Migrations; | |
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; | |
using MyApp.Data; | |
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; | |
#nullable disable | |
namespace MyApp.Migrations | |
{ | |
[DbContext(typeof(ApplicationDbContext))] | |
[Migration("20240301000000_CreateIdentitySchema")] | |
partial class CreateIdentitySchema | |
{ | |
/// <inheritdoc /> | |
protected override void BuildTargetModel(ModelBuilder modelBuilder) | |
{ | |
#pragma warning disable 612, 618 | |
modelBuilder | |
.HasAnnotation("ProductVersion", "8.0.2") | |
.HasAnnotation("Relational:MaxIdentifierLength", 63); | |
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => | |
{ | |
b.Property<string>("Id") | |
.HasColumnType("text"); | |
b.Property<string>("ConcurrencyStamp") | |
.IsConcurrencyToken() | |
.HasColumnType("text"); | |
b.Property<string>("Name") | |
.HasMaxLength(256) | |
.HasColumnType("character varying(256)"); | |
b.Property<string>("NormalizedName") | |
.HasMaxLength(256) | |
.HasColumnType("character varying(256)"); | |
b.HasKey("Id"); | |
b.HasIndex("NormalizedName") | |
.IsUnique() | |
.HasDatabaseName("RoleNameIndex"); | |
b.ToTable("AspNetRoles", (string)null); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b => | |
{ | |
b.Property<int>("Id") | |
.ValueGeneratedOnAdd() | |
.HasColumnType("integer"); | |
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id")); | |
b.Property<string>("ClaimType") | |
.HasColumnType("text"); | |
b.Property<string>("ClaimValue") | |
.HasColumnType("text"); | |
b.Property<string>("RoleId") | |
.IsRequired() | |
.HasColumnType("text"); | |
b.HasKey("Id"); | |
b.HasIndex("RoleId"); | |
b.ToTable("AspNetRoleClaims", (string)null); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b => | |
{ | |
b.Property<int>("Id") | |
.ValueGeneratedOnAdd() | |
.HasColumnType("integer"); | |
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id")); | |
b.Property<string>("ClaimType") | |
.HasColumnType("text"); | |
b.Property<string>("ClaimValue") | |
.HasColumnType("text"); | |
b.Property<string>("UserId") | |
.IsRequired() | |
.HasColumnType("text"); | |
b.HasKey("Id"); | |
b.HasIndex("UserId"); | |
b.ToTable("AspNetUserClaims", (string)null); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b => | |
{ | |
b.Property<string>("LoginProvider") | |
.HasColumnType("text"); | |
b.Property<string>("ProviderKey") | |
.HasColumnType("text"); | |
b.Property<string>("ProviderDisplayName") | |
.HasColumnType("text"); | |
b.Property<string>("UserId") | |
.IsRequired() | |
.HasColumnType("text"); | |
b.HasKey("LoginProvider", "ProviderKey"); | |
b.HasIndex("UserId"); | |
b.ToTable("AspNetUserLogins", (string)null); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b => | |
{ | |
b.Property<string>("UserId") | |
.HasColumnType("text"); | |
b.Property<string>("RoleId") | |
.HasColumnType("text"); | |
b.HasKey("UserId", "RoleId"); | |
b.HasIndex("RoleId"); | |
b.ToTable("AspNetUserRoles", (string)null); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b => | |
{ | |
b.Property<string>("UserId") | |
.HasColumnType("text"); | |
b.Property<string>("LoginProvider") | |
.HasColumnType("text"); | |
b.Property<string>("Name") | |
.HasColumnType("text"); | |
b.Property<string>("Value") | |
.HasColumnType("text"); | |
b.HasKey("UserId", "LoginProvider", "Name"); | |
b.ToTable("AspNetUserTokens", (string)null); | |
}); | |
modelBuilder.Entity("MyApp.Data.ApplicationUser", b => | |
{ | |
b.Property<string>("Id") | |
.HasColumnType("text"); | |
b.Property<int>("AccessFailedCount") | |
.HasColumnType("integer"); | |
b.Property<string>("ConcurrencyStamp") | |
.IsConcurrencyToken() | |
.HasColumnType("text"); | |
b.Property<string>("DisplayName") | |
.HasColumnType("text"); | |
b.Property<string>("Email") | |
.HasMaxLength(256) | |
.HasColumnType("character varying(256)"); | |
b.Property<bool>("EmailConfirmed") | |
.HasColumnType("boolean"); | |
b.Property<string>("FirstName") | |
.HasColumnType("text"); | |
b.Property<string>("LastName") | |
.HasColumnType("text"); | |
b.Property<bool>("LockoutEnabled") | |
.HasColumnType("boolean"); | |
b.Property<DateTimeOffset?>("LockoutEnd") | |
.HasColumnType("timestamp with time zone"); | |
b.Property<string>("NormalizedEmail") | |
.HasMaxLength(256) | |
.HasColumnType("character varying(256)"); | |
b.Property<string>("NormalizedUserName") | |
.HasMaxLength(256) | |
.HasColumnType("character varying(256)"); | |
b.Property<string>("PasswordHash") | |
.HasColumnType("text"); | |
b.Property<string>("PhoneNumber") | |
.HasColumnType("text"); | |
b.Property<bool>("PhoneNumberConfirmed") | |
.HasColumnType("boolean"); | |
b.Property<string>("ProfileUrl") | |
.HasColumnType("text"); | |
b.Property<string>("SecurityStamp") | |
.HasColumnType("text"); | |
b.Property<bool>("TwoFactorEnabled") | |
.HasColumnType("boolean"); | |
b.Property<string>("UserName") | |
.HasMaxLength(256) | |
.HasColumnType("character varying(256)"); | |
b.HasKey("Id"); | |
b.HasIndex("NormalizedEmail") | |
.HasDatabaseName("EmailIndex"); | |
b.HasIndex("NormalizedUserName") | |
.IsUnique() | |
.HasDatabaseName("UserNameIndex"); | |
b.ToTable("AspNetUsers", (string)null); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b => | |
{ | |
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) | |
.WithMany() | |
.HasForeignKey("RoleId") | |
.OnDelete(DeleteBehavior.Cascade) | |
.IsRequired(); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b => | |
{ | |
b.HasOne("MyApp.Data.ApplicationUser", null) | |
.WithMany() | |
.HasForeignKey("UserId") | |
.OnDelete(DeleteBehavior.Cascade) | |
.IsRequired(); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b => | |
{ | |
b.HasOne("MyApp.Data.ApplicationUser", null) | |
.WithMany() | |
.HasForeignKey("UserId") | |
.OnDelete(DeleteBehavior.Cascade) | |
.IsRequired(); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b => | |
{ | |
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) | |
.WithMany() | |
.HasForeignKey("RoleId") | |
.OnDelete(DeleteBehavior.Cascade) | |
.IsRequired(); | |
b.HasOne("MyApp.Data.ApplicationUser", null) | |
.WithMany() | |
.HasForeignKey("UserId") | |
.OnDelete(DeleteBehavior.Cascade) | |
.IsRequired(); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b => | |
{ | |
b.HasOne("MyApp.Data.ApplicationUser", null) | |
.WithMany() | |
.HasForeignKey("UserId") | |
.OnDelete(DeleteBehavior.Cascade) | |
.IsRequired(); | |
}); | |
#pragma warning restore 612, 618 | |
} | |
} | |
} |
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
// <auto-generated /> | |
using System; | |
using Microsoft.EntityFrameworkCore; | |
using Microsoft.EntityFrameworkCore.Infrastructure; | |
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; | |
using MyApp.Data; | |
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; | |
#nullable disable | |
namespace MyApp.Migrations | |
{ | |
[DbContext(typeof(ApplicationDbContext))] | |
partial class ApplicationDbContextModelSnapshot : ModelSnapshot | |
{ | |
protected override void BuildModel(ModelBuilder modelBuilder) | |
{ | |
#pragma warning disable 612, 618 | |
modelBuilder | |
.HasAnnotation("ProductVersion", "8.0.2") | |
.HasAnnotation("Relational:MaxIdentifierLength", 63); | |
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => | |
{ | |
b.Property<string>("Id") | |
.HasColumnType("text"); | |
b.Property<string>("ConcurrencyStamp") | |
.IsConcurrencyToken() | |
.HasColumnType("text"); | |
b.Property<string>("Name") | |
.HasMaxLength(256) | |
.HasColumnType("character varying(256)"); | |
b.Property<string>("NormalizedName") | |
.HasMaxLength(256) | |
.HasColumnType("character varying(256)"); | |
b.HasKey("Id"); | |
b.HasIndex("NormalizedName") | |
.IsUnique() | |
.HasDatabaseName("RoleNameIndex"); | |
b.ToTable("AspNetRoles", (string)null); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b => | |
{ | |
b.Property<int>("Id") | |
.ValueGeneratedOnAdd() | |
.HasColumnType("integer"); | |
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id")); | |
b.Property<string>("ClaimType") | |
.HasColumnType("text"); | |
b.Property<string>("ClaimValue") | |
.HasColumnType("text"); | |
b.Property<string>("RoleId") | |
.IsRequired() | |
.HasColumnType("text"); | |
b.HasKey("Id"); | |
b.HasIndex("RoleId"); | |
b.ToTable("AspNetRoleClaims", (string)null); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b => | |
{ | |
b.Property<int>("Id") | |
.ValueGeneratedOnAdd() | |
.HasColumnType("integer"); | |
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id")); | |
b.Property<string>("ClaimType") | |
.HasColumnType("text"); | |
b.Property<string>("ClaimValue") | |
.HasColumnType("text"); | |
b.Property<string>("UserId") | |
.IsRequired() | |
.HasColumnType("text"); | |
b.HasKey("Id"); | |
b.HasIndex("UserId"); | |
b.ToTable("AspNetUserClaims", (string)null); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b => | |
{ | |
b.Property<string>("LoginProvider") | |
.HasColumnType("text"); | |
b.Property<string>("ProviderKey") | |
.HasColumnType("text"); | |
b.Property<string>("ProviderDisplayName") | |
.HasColumnType("text"); | |
b.Property<string>("UserId") | |
.IsRequired() | |
.HasColumnType("text"); | |
b.HasKey("LoginProvider", "ProviderKey"); | |
b.HasIndex("UserId"); | |
b.ToTable("AspNetUserLogins", (string)null); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b => | |
{ | |
b.Property<string>("UserId") | |
.HasColumnType("text"); | |
b.Property<string>("RoleId") | |
.HasColumnType("text"); | |
b.HasKey("UserId", "RoleId"); | |
b.HasIndex("RoleId"); | |
b.ToTable("AspNetUserRoles", (string)null); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b => | |
{ | |
b.Property<string>("UserId") | |
.HasColumnType("text"); | |
b.Property<string>("LoginProvider") | |
.HasColumnType("text"); | |
b.Property<string>("Name") | |
.HasColumnType("text"); | |
b.Property<string>("Value") | |
.HasColumnType("text"); | |
b.HasKey("UserId", "LoginProvider", "Name"); | |
b.ToTable("AspNetUserTokens", (string)null); | |
}); | |
modelBuilder.Entity("MyApp.Data.ApplicationUser", b => | |
{ | |
b.Property<string>("Id") | |
.HasColumnType("text"); | |
b.Property<int>("AccessFailedCount") | |
.HasColumnType("integer"); | |
b.Property<string>("ConcurrencyStamp") | |
.IsConcurrencyToken() | |
.HasColumnType("text"); | |
b.Property<string>("DisplayName") | |
.HasColumnType("text"); | |
b.Property<string>("Email") | |
.HasMaxLength(256) | |
.HasColumnType("character varying(256)"); | |
b.Property<bool>("EmailConfirmed") | |
.HasColumnType("boolean"); | |
b.Property<string>("FirstName") | |
.HasColumnType("text"); | |
b.Property<string>("LastName") | |
.HasColumnType("text"); | |
b.Property<bool>("LockoutEnabled") | |
.HasColumnType("boolean"); | |
b.Property<DateTimeOffset?>("LockoutEnd") | |
.HasColumnType("timestamp with time zone"); | |
b.Property<string>("NormalizedEmail") | |
.HasMaxLength(256) | |
.HasColumnType("character varying(256)"); | |
b.Property<string>("NormalizedUserName") | |
.HasMaxLength(256) | |
.HasColumnType("character varying(256)"); | |
b.Property<string>("PasswordHash") | |
.HasColumnType("text"); | |
b.Property<string>("PhoneNumber") | |
.HasColumnType("text"); | |
b.Property<bool>("PhoneNumberConfirmed") | |
.HasColumnType("boolean"); | |
b.Property<string>("ProfileUrl") | |
.HasColumnType("text"); | |
b.Property<string>("SecurityStamp") | |
.HasColumnType("text"); | |
b.Property<bool>("TwoFactorEnabled") | |
.HasColumnType("boolean"); | |
b.Property<string>("UserName") | |
.HasMaxLength(256) | |
.HasColumnType("character varying(256)"); | |
b.HasKey("Id"); | |
b.HasIndex("NormalizedEmail") | |
.HasDatabaseName("EmailIndex"); | |
b.HasIndex("NormalizedUserName") | |
.IsUnique() | |
.HasDatabaseName("UserNameIndex"); | |
b.ToTable("AspNetUsers", (string)null); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b => | |
{ | |
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) | |
.WithMany() | |
.HasForeignKey("RoleId") | |
.OnDelete(DeleteBehavior.Cascade) | |
.IsRequired(); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b => | |
{ | |
b.HasOne("MyApp.Data.ApplicationUser", null) | |
.WithMany() | |
.HasForeignKey("UserId") | |
.OnDelete(DeleteBehavior.Cascade) | |
.IsRequired(); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b => | |
{ | |
b.HasOne("MyApp.Data.ApplicationUser", null) | |
.WithMany() | |
.HasForeignKey("UserId") | |
.OnDelete(DeleteBehavior.Cascade) | |
.IsRequired(); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b => | |
{ | |
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) | |
.WithMany() | |
.HasForeignKey("RoleId") | |
.OnDelete(DeleteBehavior.Cascade) | |
.IsRequired(); | |
b.HasOne("MyApp.Data.ApplicationUser", null) | |
.WithMany() | |
.HasForeignKey("UserId") | |
.OnDelete(DeleteBehavior.Cascade) | |
.IsRequired(); | |
}); | |
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b => | |
{ | |
b.HasOne("MyApp.Data.ApplicationUser", null) | |
.WithMany() | |
.HasForeignKey("UserId") | |
.OnDelete(DeleteBehavior.Cascade) | |
.IsRequired(); | |
}); | |
#pragma warning restore 612, 618 | |
} | |
} | |
} |
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
using System.Data; | |
using ServiceStack.DataAnnotations; | |
using ServiceStack.OrmLite; | |
namespace MyApp.Migrations; | |
public class Migration1000 : MigrationBase | |
{ | |
public class Booking : AuditBase | |
{ | |
[AutoIncrement] | |
public int Id { get; set; } | |
public string Name { get; set; } = default!; | |
public RoomType RoomType { get; set; } | |
public int RoomNumber { get; set; } | |
public DateTime BookingStartDate { get; set; } | |
public DateTime? BookingEndDate { get; set; } | |
public decimal Cost { get; set; } | |
public string? Notes { get; set; } | |
public bool? Cancelled { get; set; } | |
[References(typeof(Coupon))] | |
public string? CouponId { get; set; } | |
} | |
public class Coupon | |
{ | |
public string Id { get; set; } = default!; | |
public string Description { get; set; } = default!; | |
public int Discount { get; set; } | |
public DateTime ExpiryDate { get; set; } | |
} | |
public enum RoomType | |
{ | |
Queen, | |
Double, | |
Suite, | |
} | |
public override void Up() | |
{ | |
Db.CreateTable<Coupon>(); | |
Db.CreateTable<Booking>(); | |
new[] { 5, 10, 15, 20, 25, 30, 40, 50, 60, 70, }.Each(percent => { | |
Db.Insert(new Coupon | |
{ | |
Id = $"BOOK{percent}", | |
Description = $"{percent}% off", | |
Discount = percent, | |
ExpiryDate = DateTime.UtcNow.AddDays(30) | |
}); | |
}); | |
CreateBooking(Db, "First Booking!", RoomType.Queen, 10, 100, "BOOK10", "employee@email.com"); | |
CreateBooking(Db, "Booking 2", RoomType.Double, 12, 120, "BOOK25", "manager@email.com"); | |
CreateBooking(Db, "Booking the 3rd", RoomType.Suite, 13, 130, null, "employee@email.com"); | |
} | |
public void CreateBooking(IDbConnection? db, | |
string name, RoomType type, int roomNo, decimal cost, string? couponId, string by) => | |
db.Insert(new Booking | |
{ | |
Name = name, | |
RoomType = type, | |
RoomNumber = roomNo, | |
Cost = cost, | |
BookingStartDate = DateTime.UtcNow.AddDays(roomNo), | |
BookingEndDate = DateTime.UtcNow.AddDays(roomNo + 7), | |
CouponId = couponId, | |
CreatedBy = by, | |
CreatedDate = DateTime.UtcNow, | |
ModifiedBy = by, | |
ModifiedDate = DateTime.UtcNow, | |
}); | |
public override void Down() | |
{ | |
Db.DropTable<Booking>(); | |
Db.DropTable<Coupon>(); | |
} | |
} |
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
[ | |
{ "op":"add", "path":"/scripts/postinstall", "value":"dotnet run --AppTasks=migrate" }, | |
{ "op":"add", "path":"/scripts/migrate", "value":"dotnet run --AppTasks=migrate" }, | |
{ "op":"add", "path":"/scripts/revert:last", "value":"dotnet run --AppTasks=migrate.revert:last" }, | |
{ "op":"add", "path":"/scripts/revert:all", "value":"dotnet run --AppTasks=migrate.revert:all" }, | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment