You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

440 lines
17 KiB
C#

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Haoliang.Data.Entities;
using Haoliang.Models.System;
namespace Haoliang.Data
{
public class CNCBusinessDbContext : DbContext
{
public CNCBusinessDbContext(DbContextOptions<CNCBusinessDbContext> options) : base(options) { }
// Device Management
public DbSet<Models.Device.CNCDevice> Devices { get; set; }
public DbSet<Models.Device.DeviceCurrentStatus> DeviceCurrentStatus { get; set; }
public DbSet<Models.DataCollection.TagData> TagData { get; set; }
// DeviceStatus as string property (since it's an enum)
public string DeviceStatus { get; set; } = null!;
// Template Management
public DbSet<Models.Template.CNCBrandTemplate> CNCTemplates { get; set; }
public DbSet<Models.Template.TagMapping> TagMappings { get; set; }
// Production Management
public DbSet<Models.Production.ProductionRecord> ProductionRecords { get; set; }
public DbSet<Models.Production.ProgramProductionSummary> ProgramProductionSummary { get; set; }
public DbSet<Models.Production.ProductionSummary> ProductionSummaries { get; set; }
// User Management
public DbSet<Models.User.User> Users { get; set; }
public DbSet<Models.User.Role> Roles { get; set; }
public DbSet<Models.User.Employee> Employees { get; set; }
public DbSet<Models.User.UserPermission> UserPermissions { get; set; }
public DbSet<Models.User.RolePermission> RolePermissions { get; set; }
public DbSet<Models.User.UserSession> UserSessions { get; set; }
public DbSet<Models.User.PasswordReset> PasswordResets { get; set; }
// System Management
public DbSet<Models.System.Alarm> Alarms { get; set; }
public DbSet<Models.System.AlarmRule> AlarmRules { get; set; }
public DbSet<Models.System.AlarmNotification> AlarmNotifications { get; set; }
public DbSet<Models.System.SystemConfig> SystemConfigs { get; set; }
public DbSet<Models.System.LogEntry> LogEntries { get; set; }
public DbSet<Models.System.StatisticRule> StatisticRules { get; set; }
public DbSet<Models.System.StatisticResult> StatisticResults { get; set; }
// Data Collection
public DbSet<Models.DataCollection.CollectionTask> CollectionTasks { get; set; }
public DbSet<Models.DataCollection.CollectionResult> CollectionResults { get; set; }
public DbSet<Models.DataCollection.CollectionLog> CollectionLogs { get; set; }
public DbSet<Models.DataCollection.CollectionConfig> CollectionConfigs { get; set; }
// Scheduled Tasks
public DbSet<Models.System.ScheduledTask> ScheduledTasks { get; set; }
public DbSet<Models.System.TaskExecutionResult> TaskExecutionResults { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Configure MySQL-specific settings
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
// Set default charset and collation
if (typeof(BaseEntity).IsAssignableFrom(entityType.ClrType))
{
modelBuilder.Entity(entityType.ClrType)
.ToTable(entityType.GetTableName() ?? "", t => t
.charset("utf8mb4")
.collation("utf8mb4_unicode_ci"));
}
}
// Configure relationships
ConfigureDeviceRelationships(modelBuilder);
ConfigureUserRelationships(modelBuilder);
ConfigureAlarmRelationships(modelBuilder);
ConfigureCollectionRelationships(modelBuilder);
ConfigureProductionRelationships(modelBuilder);
ConfigureTemplateRelationships(modelBuilder);
// Configure indexes
ConfigureIndexes(modelBuilder);
// Configure constraints
ConfigureConstraints(modelBuilder);
// Configure data conversions
ConfigureDataConversions(modelBuilder);
}
private void ConfigureDeviceRelationships(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.Device.CNCDevice>()
.HasMany(d => d.DeviceStatus)
.WithOne()
.HasForeignKey(ds => ds.DeviceId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Models.Device.CNCDevice>()
.HasMany(d => d.CollectionResults)
.WithOne()
.HasForeignKey(cr => cr.DeviceId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Models.Device.CNCDevice>()
.HasMany(d => d.CollectionLogs)
.WithOne()
.HasForeignKey(cl => cl.DeviceId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Models.Device.CNCDevice>()
.HasMany(d => d.ProductionRecords)
.WithOne()
.HasForeignKey(pr => pr.DeviceId)
.OnDelete(DeleteBehavior.Cascade);
}
private void ConfigureUserRelationships(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.User.User>()
.HasOne(u => u.Role)
.WithMany()
.HasForeignKey(u => u.RoleId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Models.User.User>()
.HasMany(u => u.UserPermissions)
.WithOne(up => up.User)
.HasForeignKey(up => up.UserId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Models.User.User>()
.HasMany(u => u.UserSessions)
.WithOne(us => us.User)
.HasForeignKey(us => us.UserId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Models.User.User>()
.HasMany(u => u.PasswordResets)
.WithOne(pr => pr.User)
.HasForeignKey(pr => pr.UserId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Models.User.Role>()
.HasMany(r => r.RolePermissions)
.WithOne(rp => rp.Role)
.HasForeignKey(rp => rp.RoleId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Models.User.Employee>()
.HasMany(e => e.DeviceAssignments)
.WithOne(da => da.Employee)
.HasForeignKey(da => da.EmployeeId)
.OnDelete(DeleteBehavior.Cascade);
}
private void ConfigureAlarmRelationships(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.System.Alarm>()
.HasMany(a => a.AlarmNotifications)
.WithOne(an => an.Alarm)
.HasForeignKey(an => an.AlarmId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Models.System.AlarmRule>()
.HasMany(ar => ar.Alarms)
.WithOne(a => a.AlarmRule)
.HasForeignKey(a => a.AlarmRuleId)
.OnDelete(DeleteBehavior.Restrict);
}
private void ConfigureCollectionRelationships(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.DataCollection.CollectionTask>()
.HasMany(ct => ct.CollectionResults)
.WithOne(cr => cr.CollectionTask)
.HasForeignKey(cr => cr.TaskId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Models.DataCollection.CollectionResult>()
.HasMany(cr => cr.CollectionLogs)
.WithOne(cl => cl.CollectionResult)
.HasForeignKey(cl => cl.ResultId)
.OnDelete(DeleteBehavior.Cascade);
}
private void ConfigureProductionRelationships(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.Production.ProductionRecord>()
.HasMany(pr => pr.ProgramSummaries)
.WithOne(pps => pps.ProductionRecord)
.HasForeignKey(pps => pps.RecordId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Models.Device.CNCDevice>()
.HasMany(d => d.ProductionSummaries)
.WithOne(ps => ps.Device)
.HasForeignKey(ps => ps.DeviceId)
.OnDelete(DeleteBehavior.Cascade);
}
private void ConfigureTemplateRelationships(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.Template.CNCBrandTemplate>()
.HasMany(t => t.TagMappings)
.WithOne(tm => tm.Template)
.HasForeignKey(tm => tm.TemplateId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Models.Template.CNCBrandTemplate>()
.HasMany(t => t.Devices)
.WithOne(d => d.Template)
.HasForeignKey(d => d.TemplateId)
.OnDelete(DeleteBehavior.Restrict);
}
private void ConfigureIndexes(ModelBuilder modelBuilder)
{
// Device indexes
modelBuilder.Entity<Models.Device.CNCDevice>()
.HasIndex(d => d.DeviceCode)
.IsUnique();
modelBuilder.Entity<Models.Device.CNCDevice>()
.HasIndex(d => d.IPAddress);
modelBuilder.Entity<Models.Device.CNCDevice>()
.HasIndex(d => d.IsOnline);
modelBuilder.Entity<Models.Device.CNCDevice>()
.HasIndex(d => d.IsAvailable);
// User indexes
modelBuilder.Entity<Models.User.User>()
.HasIndex(u => u.Username)
.IsUnique();
modelBuilder.Entity<Models.User.User>()
.HasIndex(u => u.Email)
.IsUnique();
modelBuilder.Entity<Models.User.User>()
.HasIndex(u => u.IsActive);
// Alarm indexes
modelBuilder.Entity<Models.System.Alarm>()
.HasIndex(a => a.AlarmStatus);
modelBuilder.Entity<Models.System.Alarm>()
.HasIndex(a => a.IsActive);
modelBuilder.Entity<Models.System.Alarm>()
.HasIndex(a => a.CreateTime);
// Collection indexes
modelBuilder.Entity<Models.DataCollection.CollectionResult>()
.HasIndex(cr => cr.DeviceId);
modelBuilder.Entity<Models.DataCollection.CollectionResult>()
.HasIndex(cr => cr.CollectionTime);
modelBuilder.Entity<Models.DataCollection.CollectionResult>()
.HasIndex(cr => cr.IsSuccess);
// Production indexes
modelBuilder.Entity<Models.Production.ProductionRecord>()
.HasIndex(pr => pr.DeviceId);
modelBuilder.Entity<Models.Production.ProductionRecord>()
.HasIndex(pr => pr.ProductionDate);
modelBuilder.Entity<Models.Production.ProductionRecord>()
.HasIndex(pr => pr.IsCompleted);
// Template indexes
modelBuilder.Entity<Models.Template.CNCBrandTemplate>()
.HasIndex(t => t.BrandName);
modelBuilder.Entity<Models.Template.CNCBrandTemplate>()
.HasIndex(t => t.IsActive);
// System config indexes
modelBuilder.Entity<Models.System.SystemConfig>()
.HasIndex(sc => sc.ConfigKey)
.IsUnique();
modelBuilder.Entity<Models.System.SystemConfig>()
.HasIndex(sc => sc.Category);
modelBuilder.Entity<Models.System.SystemConfig>()
.HasIndex(sc => sc.IsActive);
}
private void ConfigureConstraints(ModelBuilder modelBuilder)
{
// Device constraints
modelBuilder.Entity<Models.Device.CNCDevice>()
.Property(d => d.DeviceCode)
.IsRequired()
.HasMaxLength(50);
modelBuilder.Entity<Models.Device.CNCDevice>()
.Property(d => d.DeviceName)
.IsRequired()
.HasMaxLength(100);
modelBuilder.Entity<Models.Device.CNCDevice>()
.Property(d => d.IPAddress)
.IsRequired()
.HasMaxLength(15);
modelBuilder.Entity<Models.Device.CNCDevice>()
.Property(d => d.HttpUrl)
.IsRequired()
.HasMaxLength(255);
modelBuilder.Entity<Models.Device.CNCDevice>()
.Property(d => d.CollectionInterval)
.IsRequired();
// User constraints
modelBuilder.Entity<Models.User.User>()
.Property(u => u.Username)
.IsRequired()
.HasMaxLength(50);
modelBuilder.Entity<Models.User.User>()
.Property(u => u.Email)
.IsRequired()
.HasMaxLength(100);
modelBuilder.Entity<Models.User.User>()
.Property(u => u.PasswordHash)
.IsRequired()
.HasMaxLength(255);
modelBuilder.Entity<Models.User.User>()
.Property(u => u.FirstName)
.IsRequired()
.HasMaxLength(50);
modelBuilder.Entity<Models.User.User>()
.Property(u => u.LastName)
.IsRequired()
.HasMaxLength(50);
// Alarm constraints
modelBuilder.Entity<Models.System.Alarm>()
.Property(a => a.AlarmType)
.IsRequired()
.HasMaxLength(50);
modelBuilder.Entity<Models.System.Alarm>()
.Property(a => a.Title)
.IsRequired()
.HasMaxLength(255);
modelBuilder.Entity<Models.System.Alarm>()
.Property(a => a.AlarmStatus)
.IsRequired();
// System config constraints
modelBuilder.Entity<Models.System.SystemConfig>()
.Property(sc => sc.ConfigKey)
.IsRequired()
.HasMaxLength(100);
modelBuilder.Entity<Models.System.SystemConfig>()
.Property(sc => sc.ConfigValue)
.IsRequired();
modelBuilder.Entity<Models.System.SystemConfig>()
.Property(sc => sc.Category)
.IsRequired()
.HasMaxLength(50);
}
private void ConfigureDataConversions(ModelBuilder modelBuilder)
{
// Configure decimal properties with appropriate precision
modelBuilder.Entity<Models.Production.ProductionSummary>()
.Property(ps => ps.QualityRate)
.HasColumnType("decimal(5,2)");
modelBuilder.Entity<Models.System.SystemConfig>()
.Property(sc => sc.ConfigValue)
.HasColumnType("text");
modelBuilder.Entity<Models.DataCollection.CollectionLog>()
.Property(cl => cl.LogData)
.HasColumnType("text");
modelBuilder.Entity<Models.DataCollection.CollectionResult>()
.Property(cr => cr.RawData)
.HasColumnType("text");
modelBuilder.Entity<Models.DataCollection.CollectionResult>()
.Property(cr => cr.ParsedData)
.HasColumnType("text");
modelBuilder.Entity<Models.Template.CNCBrandTemplate>()
.Property(t => t.TagsJson)
.HasColumnType("json");
modelBuilder.Entity<Models.Template.CNCBrandTemplate>()
.Property(t => t.DataProcessingRulesJson)
.HasColumnType("json");
modelBuilder.Entity<Models.System.StatisticResult>()
.Property(sr => sr.ResultData)
.HasColumnType("json");
}
public static void ConfigureDatabaseServices(IServiceCollection services, IConfiguration configuration)
{
var connectionString = configuration.GetConnectionString("CNCBusinessDb");
services.AddDbContext<CNCBusinessDbContext>(options =>
{
options.UseMySql(connectionString,
mysqlOptions =>
{
mysqlOptions.EnableRetryOnFailure(
maxRetryCount: 3,
maxRetryDelay: TimeSpan.FromSeconds(30),
errorNumbersToAdd: null);
mysqlOptions.EnableSensitiveDataLogging(true);
});
// Enable lazy loading for development
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development")
{
options.EnableSensitiveDataLogging();
options.EnableDetailedErrors();
}
});
}
}
}