using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; namespace AyaNova.Models { public partial class AyContext : DbContext { public virtual DbSet GlobalBizSettings { get; set; } public virtual DbSet Event { get; set; } public virtual DbSet SearchDictionary { get; set; } public virtual DbSet SearchKey { get; set; } public virtual DbSet User { get; set; } public virtual DbSet UserOptions { get; set; } public virtual DbSet License { get; set; } public virtual DbSet Widget { get; set; } public virtual DbSet FileAttachment { get; set; } public virtual DbSet OpsJob { get; set; } public virtual DbSet OpsJobLog { get; set; } public virtual DbSet Translation { get; set; } public virtual DbSet TranslationItem { get; set; } public virtual DbSet DataListView { get; set; } public virtual DbSet Tag { get; set; } public virtual DbSet FormCustom { get; set; } public virtual DbSet PickListTemplate { get; set; } //Note: had to add this constructor to work with the code in startup.cs that gets the connection string from the appsettings.json file //and commented out the above on configuring public AyContext(DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { //AUTOMATICALLY MATCH NAMES //https://andrewlock.net/customising-asp-net-core-identity-ef-core-naming-conventions-for-postgresql/ foreach (var entity in modelBuilder.Model.GetEntityTypes()) { // Replace table names //entity.Relational().TableName = "a" + entity.Relational().TableName.ToLowerInvariant(); entity.SetTableName("a" + entity.GetTableName().ToLowerInvariant()); // Replace column names foreach (var property in entity.GetProperties()) { //Any object that has a concurrencytoken field //set it up to work properly with PostgreSQL if (property.Name == "ConcurrencyToken") { property.SetColumnName("xmin"); property.SetColumnType("xid"); // property.Relational().ColumnName = "xmin"; // property.Relational().ColumnType = "xid"; property.ValueGenerated = ValueGenerated.OnAddOrUpdate; property.IsConcurrencyToken = true; } else property.SetColumnName(property.Name.ToLowerInvariant()); } foreach (var key in entity.GetKeys()) { key.SetName(key.GetName().ToLowerInvariant()); // key.Relational().Name = key.Relational().Name.ToLowerInvariant(); } foreach (var key in entity.GetForeignKeys()) { //key.Relational().Name = key.Relational().Name.ToLowerInvariant(); key.SetConstraintName(key.GetConstraintName().ToLowerInvariant()); } foreach (var index in entity.GetIndexes()) { index.SetName(index.GetName().ToLowerInvariant()); //index.Relational().Name = index.Relational().Name.ToLowerInvariant(); } } //Indexes must be specified through fluent api unfortunately modelBuilder.Entity().HasIndex(p => p.StoredFileName); //Relationships modelBuilder.Entity() .HasMany(c => c.TranslationItems) .WithOne(e => e.Translation) .IsRequired();//default delete behaviour is cascade when set to isrequired modelBuilder.Entity() .HasOne(p => p.UserOptions) .WithOne(i => i.User) .HasForeignKey(b => b.UserId) .OnDelete(DeleteBehavior.Cascade);//Hopefully will delete the useroptions with the user? //User->Widget Not certain about this definition modelBuilder.Entity() .HasOne(p => p.Widget) .WithOne(i => i.User) .HasForeignKey(b => b.UserId) .OnDelete(DeleteBehavior.NoAction); //----------- } } }