118 lines
4.9 KiB
C#
118 lines
4.9 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using YAPContracts.Enums;
|
|
using YAPContracts.Infrastructure;
|
|
using YAPDatabase.Models;
|
|
|
|
namespace YAPDatabase
|
|
{
|
|
internal class YAPDbContext(IConfigurationDatabase configuration) : DbContext
|
|
{
|
|
private readonly IConfigurationDatabase _configuration = configuration;
|
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
|
{
|
|
if (!optionsBuilder.IsConfigured)
|
|
{
|
|
optionsBuilder.UseNpgsql(_configuration?.ConnectionString, o => o.SetPostgresVersion(12, 2));
|
|
base.OnConfiguring(optionsBuilder);
|
|
}
|
|
}
|
|
|
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
{
|
|
// one Table-per-Hierarchy (TPH) for Users
|
|
modelBuilder.Entity<User>()
|
|
.HasDiscriminator<UserType>("Role")
|
|
.HasValue<Worker>(UserType.Worker)
|
|
.HasValue<Storekeeper>(UserType.Storekeeper);
|
|
|
|
modelBuilder.Entity<User>()
|
|
.HasKey(u => u.Id);
|
|
|
|
modelBuilder.Entity<User>()
|
|
.Property(u => u.Login).IsRequired();
|
|
modelBuilder.Entity<User>()
|
|
.Property(u => u.Email).IsRequired();
|
|
modelBuilder.Entity<User>()
|
|
.Property(u => u.PasswordHash).IsRequired();
|
|
|
|
// intermediate tables for many-to-many relationships
|
|
modelBuilder.Entity<ComponentInProduct>()
|
|
.HasKey(x => new { x.ComponentId, x.ProductId });
|
|
|
|
modelBuilder.Entity<ComponentInProductSet>()
|
|
.HasKey(x => new { x.ComponentId, x.ProductSetId });
|
|
|
|
modelBuilder.Entity<ProductInPurchase>()
|
|
.HasKey(x => new { x.ProductId, x.PurchaseId });
|
|
|
|
modelBuilder.Entity<ProductSetInPurchase>()
|
|
.HasKey(x => new { x.ProductSetId, x.PurchaseId });
|
|
|
|
// onlyActual & isDeleted properties for soft delete
|
|
modelBuilder.Entity<ProductSet>()
|
|
.Property(ps => ps.IsDeleted)
|
|
.HasDefaultValue(false);
|
|
|
|
modelBuilder.Entity<ProductSet>()
|
|
.HasIndex(e => new { e.SetName, e.IsDeleted })
|
|
.IsUnique()
|
|
.HasFilter("\"IsDeleted\" = FALSE"); // unique index for non-deleted sets
|
|
|
|
modelBuilder.Entity<Product>()
|
|
.Property(p => p.IsDeleted)
|
|
.HasDefaultValue(false);
|
|
modelBuilder.Entity<Product>()
|
|
.HasIndex(e => new { e.Name, e.IsDeleted })
|
|
.IsUnique()
|
|
.HasFilter("\"IsDeleted\" = FALSE"); // unique index for non-deleted products
|
|
|
|
modelBuilder.Entity<Component>()
|
|
.Property(c => c.IsDeleted)
|
|
.HasDefaultValue(false);
|
|
modelBuilder.Entity<Component>()
|
|
.HasIndex(e => new { e.Name, e.IsDeleted })
|
|
.IsUnique()
|
|
.HasFilter("\"IsDeleted\" = FALSE"); // unique index for non-deleted components
|
|
|
|
// User relationships
|
|
// Worker can create Purchases and Comments here
|
|
modelBuilder.Entity<Purchase>()
|
|
.HasOne<Worker>(c => c.User) // only Worker can create Purchase
|
|
.WithMany(w => w.Purchases)
|
|
.HasForeignKey(p => p.UserId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
|
|
modelBuilder.Entity<Comment>()
|
|
.HasOne<Worker>(c => c.User)
|
|
.WithMany(w => w.Comments)
|
|
.HasForeignKey(c => c.UserId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
|
|
modelBuilder.Entity<Comment>().HasOne<ProductSet>(c => c.ProductSet)
|
|
.WithMany(ps => ps.Comments)
|
|
.HasForeignKey(c => c.ProductSetId)
|
|
.OnDelete(DeleteBehavior.Cascade); // deleting a ProductSet will delete its Comments
|
|
|
|
// Storekeeper can manage Components and ProductOrders here
|
|
modelBuilder.Entity<ProductOrder>()
|
|
.HasOne<Storekeeper>(c => c.Storekeeper) // only Storekeeper can create ProductOrder
|
|
.WithMany(w => w.ProductOrders)
|
|
.HasForeignKey(p => p.UserId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
}
|
|
|
|
public DbSet<User> Users { get; set; } // single table
|
|
|
|
public DbSet<Comment> Comments { get; set; }
|
|
public DbSet<Component> Components { get; set; }
|
|
public DbSet<ComponentInProduct> ComponentsInProduct { get; set; }
|
|
public DbSet<ComponentInProductSet> ComponentsInProductSet { get; set; }
|
|
public DbSet<Product> Products { get; set; }
|
|
public DbSet<ProductInPurchase> ProductsInPurchase { get; set; }
|
|
public DbSet<ProductOrder> ProductOrders { get; set; }
|
|
public DbSet<ProductSet> ProductSets { get; set; }
|
|
public DbSet<ProductSetInPurchase> ProductSetsInPurchase { get; set; }
|
|
public DbSet<Purchase> Purchases { get; set; }
|
|
}
|
|
}
|