using Microsoft.EntityFrameworkCore; namespace RobotNet10.MapManager.Data; /// /// Database context for VDMA LIF 1.0.0 Map Manager /// public class MapDbContext(DbContextOptions options) : DbContext(options) { // DbSets public DbSet Layouts { get; set; } = null!; public DbSet LayoutVersions { get; set; } = null!; public DbSet LayoutLevels { get; set; } = null!; public DbSet VehicleTypes { get; set; } = null!; public DbSet Nodes { get; set; } = null!; public DbSet Edges { get; set; } = null!; public DbSet Stations { get; set; } = null!; public DbSet StationInteractionNodes { get; set; } = null!; public DbSet NodeVehicleProperties { get; set; } = null!; public DbSet EdgeVehicleProperties { get; set; } = null!; public DbSet LayoutLevelEditorSettings { get; set; } = null!; protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // Layout configuration modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasIndex(e => e.LayoutId).IsUnique(); entity.HasIndex(e => e.IsActive); entity.HasMany(e => e.Versions) .WithOne(e => e.Layout) .HasForeignKey(e => e.LayoutId) .OnDelete(DeleteBehavior.Cascade); }); // LayoutVersion configuration modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasIndex(e => new { e.LayoutId, e.Version }).IsUnique(); entity.HasIndex(e => e.IsActive); entity.HasMany(e => e.Levels) .WithOne(e => e.Version) .HasForeignKey(e => e.VersionId) .OnDelete(DeleteBehavior.Cascade); }); // LayoutLevel configuration modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasIndex(e => new { e.VersionId, e.LayoutLevelId }).IsUnique(); entity.HasIndex(e => e.LevelOrder); entity.HasMany(e => e.Nodes) .WithOne(e => e.Level) .HasForeignKey(e => e.LevelId) .OnDelete(DeleteBehavior.Cascade); entity.HasMany(e => e.Edges) .WithOne(e => e.Level) .HasForeignKey(e => e.LevelId) .OnDelete(DeleteBehavior.Cascade); entity.HasMany(e => e.Stations) .WithOne(e => e.Level) .HasForeignKey(e => e.LevelId) .OnDelete(DeleteBehavior.Cascade); }); // VehicleType configuration modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasIndex(e => e.VehicleTypeId).IsUnique(); entity.HasIndex(e => e.IsActive); entity.HasMany(e => e.NodeVehicleProperties) .WithOne(e => e.VehicleType) .HasForeignKey(e => e.VehicleTypeId) .OnDelete(DeleteBehavior.Cascade); entity.HasMany(e => e.EdgeVehicleProperties) .WithOne(e => e.VehicleType) .HasForeignKey(e => e.VehicleTypeId) .OnDelete(DeleteBehavior.Cascade); }); // Node configuration modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasIndex(e => new { e.LevelId, e.NodeId }).IsUnique(); entity.HasIndex(e => e.NodeId); entity.HasIndex(e => e.MapId); entity.HasIndex(e => new { e.X, e.Y }); entity.HasMany(e => e.VehicleProperties) .WithOne(e => e.Node) .HasForeignKey(e => e.NodeId) .OnDelete(DeleteBehavior.Cascade); entity.HasMany(e => e.OutgoingEdges) .WithOne(e => e.StartNode) .HasForeignKey(e => e.StartNodeId) .OnDelete(DeleteBehavior.Restrict); entity.HasMany(e => e.IncomingEdges) .WithOne(e => e.EndNode) .HasForeignKey(e => e.EndNodeId) .OnDelete(DeleteBehavior.Restrict); entity.HasMany(e => e.StationInteractions) .WithOne(e => e.Node) .HasForeignKey(e => e.NodeId) .OnDelete(DeleteBehavior.Restrict); }); // Edge configuration modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasIndex(e => new { e.LevelId, e.EdgeId }).IsUnique(); entity.HasIndex(e => e.EdgeId); entity.HasIndex(e => e.StartNodeId); entity.HasIndex(e => e.EndNodeId); entity.ToTable(t => t.HasCheckConstraint("CK_Edges_DifferentNodes", "[StartNodeId] <> [EndNodeId]")); entity.HasMany(e => e.VehicleProperties) .WithOne(e => e.Edge) .HasForeignKey(e => e.EdgeId) .OnDelete(DeleteBehavior.Cascade); }); // Station configuration modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasIndex(e => new { e.LevelId, e.StationId }).IsUnique(); entity.HasIndex(e => e.StationId); entity.HasMany(e => e.InteractionNodes) .WithOne(e => e.Station) .HasForeignKey(e => e.StationId) .OnDelete(DeleteBehavior.Cascade); }); // StationInteractionNode configuration modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasIndex(e => new { e.StationId, e.NodeId }).IsUnique(); entity.HasIndex(e => e.StationId); entity.HasIndex(e => e.NodeId); }); // NodeVehicleProperty configuration modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasIndex(e => new { e.NodeId, e.VehicleTypeId }).IsUnique(); entity.HasIndex(e => e.NodeId); entity.HasIndex(e => e.VehicleTypeId); }); // EdgeVehicleProperty configuration modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasIndex(e => new { e.EdgeId, e.VehicleTypeId }).IsUnique(); entity.HasIndex(e => e.EdgeId); entity.HasIndex(e => e.VehicleTypeId); }); // LayoutLevelEditorSettings configuration (UI extensions - not VDMA LIF) modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); // 1-to-1 relationship with LayoutLevel (unique index on LevelId) entity.HasIndex(e => e.LevelId).IsUnique(); entity.HasOne(e => e.Level) .WithOne(l => l.EditorSettings) .HasForeignKey(e => e.LevelId) .OnDelete(DeleteBehavior.Cascade); }); } }