using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using sodoff.Configuration; namespace sodoff.Model; public class DBContext : DbContext { public DbSet Users { get; set; } = null!; public DbSet Vikings { get; set; } = null!; public DbSet Dragons { get; set; } = null!; public DbSet Images { get; set; } = null!; public DbSet Sessions { get; set; } = null!; public DbSet Pairs { get; set; } = null!; public DbSet PairData { get; set; } = null!; public DbSet TaskStatuses { get; set; } = null!; public DbSet InventoryItems { get; set; } = null!; public DbSet MissionStates { get; set; } = null!; public DbSet Rooms { get; set; } = null!; public DbSet SceneData { get; set; } = null!; public DbSet RoomItems { get; set; } = null!; public DbSet GameData { get; set; } = null!; public DbSet GameDataPairs { get; set; } = null!; public DbSet AchievementPoints { get; set; } = null!; public DbSet ProfileAnswers { get; set; } = null!; public DbSet MMORoles { get; set; } = null!; public DbSet Parties { get; set; } = null!; public DbSet AchievementTaskState { get; set; } = null!; public DbSet SavedData { get; set; } = null!; public DbSet UserMissions { get; set; } = null!; public DbSet Neighborhoods { get; set; } = null!; // we had a brief debate on whether it's neighborhoods or neighborheed public DbSet Groups { get; set; } = null!; public DbSet Ratings { get; set; } = null!; public DbSet RatingRanks { get; set; } = null!; public DbSet UserMissionData { get; set; } = null!; public DbSet UserBadgesCompleted { get; set; } = null!; private readonly IOptions config; public DBContext(IOptions config) { this.config = config; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { #if USE_POSTGRESQL if (config.Value.DbProvider == DbProviders.PostgreSQL) { optionsBuilder.UseNpgsql(config.Value.DbConnection).UseLazyLoadingProxies(); return; } #endif #if USE_MYSQL if (config.Value.DbProvider == DbProviders.MySQL) { optionsBuilder.UseMySQL(config.Value.DbConnection).UseLazyLoadingProxies(); return; } #endif #if USE_SQLITE if (config.Value.DbProvider == DbProviders.SQLite) { string DbPath; if (String.IsNullOrEmpty(config.Value.DbPath)) { DbPath = Path.Join(Directory.GetCurrentDirectory(), "sodoff.db"); } else { DbPath = config.Value.DbPath; } optionsBuilder.UseSqlite($"Data Source={DbPath}").UseLazyLoadingProxies(); return; } #endif throw new Exception($"Unsupported DbProvider {config.Value.DbProvider}"); } protected override void OnModelCreating(ModelBuilder builder) { // Sessions builder.Entity().HasOne(s => s.User) .WithMany(e => e.Sessions) .HasForeignKey(e => e.UserId) .OnDelete(DeleteBehavior.Cascade); builder.Entity().HasOne(s => s.Viking) .WithMany(e => e.Sessions) .HasForeignKey(e => e.VikingId) .OnDelete(DeleteBehavior.Cascade); // Users builder.Entity().HasMany(u => u.Sessions) .WithOne(e => e.User); builder.Entity().HasMany(u => u.PairData) .WithOne(e => e.User); builder.Entity().HasMany(u => u.Vikings) .WithOne(e => e.User); // Vikings builder.Entity().HasOne(v => v.User) .WithMany(e => e.Vikings) .HasForeignKey(e => e.UserId); builder.Entity().HasMany(v => v.Dragons) .WithOne(e => e.Viking); builder.Entity().HasMany(v => v.Sessions) .WithOne(e => e.Viking); builder.Entity().HasMany(v => v.MissionStates) .WithOne(e => e.Viking); builder.Entity().HasMany(v => v.Rooms) .WithOne(e => e.Viking); builder.Entity().HasMany(v => v.SceneData) .WithOne(e => e.Viking); builder.Entity().HasMany(v => v.AchievementPoints) .WithOne(e => e.Viking); builder.Entity().HasMany(v => v.PairData) .WithOne(e => e.Viking); builder.Entity().HasMany(v => v.Images) .WithOne(e => e.Viking); builder.Entity().HasMany(v => v.TaskStatuses) .WithOne(e => e.Viking); builder.Entity().HasMany(v => v.AchievementTaskStates) .WithOne(e => e.Viking); builder.Entity().HasOne(v => v.SelectedDragon) .WithOne() .HasForeignKey(e => e.SelectedDragonId); builder.Entity().HasMany(v => v.GameData) .WithOne(e => e.Viking); builder.Entity().HasMany(v => v.SavedData) .WithOne(e => e.Viking); builder.Entity().HasMany(v => v.ProfileAnswers) .WithOne(e => e.Viking); builder.Entity().HasMany(v => v.Parties) .WithOne(e => e.Viking); builder.Entity().HasMany(v => v.MMORoles) .WithOne(e => e.Viking); builder.Entity().HasOne(v => v.Neighborhood) .WithOne(e => e.Viking); builder.Entity().HasMany(v => v.Groups) .WithMany(e => e.Vikings); builder.Entity().HasMany(v => v.Ratings) .WithOne(r => r.Viking); builder.Entity().HasMany(v => v.UserMissions) .WithOne(r => r.Viking); builder.Entity().HasMany(v => v.UserBadgesCompleted) .WithOne(r => r.Viking); // Dragons builder.Entity().HasOne(d => d.Viking) .WithMany(e => e.Dragons) .HasForeignKey(e => e.VikingId); builder.Entity().HasMany(d => d.PairData) .WithOne(e => e.Dragon); // PairData & Pair builder.Entity().HasMany(p => p.Pairs) .WithOne(e => e.PairData); builder.Entity().HasOne(p => p.Viking) .WithMany(e => e.PairData) .HasForeignKey(e => e.VikingId) .OnDelete(DeleteBehavior.Cascade); builder.Entity().HasOne(p => p.User) .WithMany(e => e.PairData) .HasForeignKey(e => e.UserId) .OnDelete(DeleteBehavior.Cascade); builder.Entity().HasOne(p => p.Dragon) .WithMany(e => e.PairData) .HasForeignKey(e => e.DragonId) .OnDelete(DeleteBehavior.Cascade); builder.Entity() .HasOne(p => p.PairData) .WithMany(pd => pd.Pairs) .HasForeignKey(p => p.MasterId) .HasPrincipalKey(e => e.Id); // Inventory & InventoryItem builder.Entity() .HasMany(v => v.InventoryItems) .WithOne(i => i.Viking); builder.Entity() .HasOne(e => e.Viking) .WithMany(e => e.InventoryItems) .HasForeignKey(e => e.VikingId); // Room & RoomItem builder.Entity().HasOne(r => r.Viking) .WithMany(e => e.Rooms) .HasForeignKey(e => e.VikingId); builder.Entity().HasMany(r => r.Items) .WithOne(e => e.Room); builder.Entity().HasOne(i => i.Room) .WithMany(r => r.Items) .HasForeignKey(e => e.RoomId); // GameData builder.Entity().HasOne(e => e.Viking) .WithMany(e => e.GameData); builder.Entity().HasMany(e => e.GameDataPairs) .WithOne(e => e.GameData); builder.Entity().HasOne(e => e.GameData) .WithMany(e => e.GameDataPairs); // Others .. builder.Entity().HasOne(s => s.Viking) .WithMany(e => e.Images) .HasForeignKey(e => e.VikingId); builder.Entity().HasKey(e => new { e.Id, e.VikingId, e.MissionId }); builder.Entity() .HasOne(t => t.Viking) .WithMany(v => v.TaskStatuses) .HasForeignKey(t => t.VikingId); builder.Entity().HasOne(m => m.Viking) .WithMany(e => e.MissionStates) .HasForeignKey(e => e.VikingId); builder.Entity().HasOne(m => m.Viking) .WithMany(e => e.AchievementTaskStates) .HasForeignKey(e => e.VikingId); builder.Entity().HasKey(e => new { e.VikingId, e.Type }); builder.Entity() .HasOne(e => e.Viking) .WithMany(e => e.AchievementPoints) .HasForeignKey(e => e.VikingId); builder.Entity().HasKey(e => new { e.VikingId, e.SaveId }); builder.Entity() .HasOne(e => e.Viking) .WithMany(v => v.SavedData) .HasForeignKey(e => e.VikingId); builder.Entity().HasOne(i => i.Viking) .WithMany(i => i.Parties); builder.Entity().HasOne(i => i.Viking) .WithMany(i => i.ProfileAnswers) .HasForeignKey(e => e.VikingId); builder.Entity().HasOne(i => i.Viking) .WithMany(i => i.SceneData) .HasForeignKey(e => e.VikingId); // MMO Roles builder.Entity().HasOne(r => r.Viking) .WithMany(e => e.MMORoles) .HasForeignKey(e => e.VikingId); // Neighborhoods builder.Entity().HasOne(r => r.Viking) .WithOne(e => e.Neighborhood) .HasForeignKey(e => e.VikingId); // Groups builder.Entity().HasMany(r => r.Vikings) .WithMany(e => e.Groups); // Rating builder.Entity().HasOne(r => r.Viking) .WithMany(v => v.Ratings) .HasForeignKey(r => r.VikingId); builder.Entity().HasOne(r => r.Rank) .WithMany(rr => rr.Ratings) .HasForeignKey(r => r.RankId); builder.Entity().HasMany(rr => rr.Ratings) .WithOne(r => r.Rank); // old ("step") missions builder.Entity().HasOne(r => r.Viking) .WithMany(v => v.UserMissions) .HasForeignKey(r => r.VikingId); builder.Entity().HasOne(r => r.Viking) .WithMany(v => v.UserBadgesCompleted) .HasForeignKey(r => r.VikingId); } }