Files
lux/EgwCoreLib.Lux.Data/DataLayerContext.cs
T

263 lines
11 KiB
C#

using Microsoft.Extensions.Configuration;
namespace EgwCoreLib.Lux.Data
{
public partial class DataLayerContext : DbContext
{
private static Logger Log = LogManager.GetCurrentClassLogger();
private IConfiguration _configuration;
public DataLayerContext()
{
}
#if false
public DataLayerContext(IConfiguration configuration)
{
_configuration = configuration;
}
#endif
public DataLayerContext(DbContextOptions<DataLayerContext> options) : base(options)
{
try
{
// se non ci fosse... crea o migra!
Database.Migrate();
}
catch (Exception exc)
{
Log.Error(exc, "Exception during context initialization 02");
}
}
public virtual DbSet<CounterModel> DbSetCounters { get; set; }
public virtual DbSet<GlassModel> DbSetConfGlass { get; set; }
public virtual DbSet<ProfileModel> DbSetConfProfile { get; set; }
public virtual DbSet<WoodModel> DbSetConfWood { get; set; }
public virtual DbSet<EnvirParamModel> DbSetEnvirPar { get; set; }
public virtual DbSet<ItemGroupModel> DbSetItemGroup { get; set; }
public virtual DbSet<ItemModel> DbSetItem { get; set; }
public virtual DbSet<SellingItemModel> DbSetSellItem { get; set; }
public virtual DbSet<TagsModel> DbSetTags { get; set; }
public virtual DbSet<CustomerModel> DbSetCustomer { get; set; }
public virtual DbSet<DealerModel> DbSetDealer { get; set; }
public virtual DbSet<SupplierModel> DbSetSupplier { get; set; }
public virtual DbSet<OfferModel> DbSetOffer { get; set; }
public virtual DbSet<OfferRowModel> DbSetOfferRow { get; set; }
public virtual DbSet<OrderModel> DbSetOrder { get; set; }
public virtual DbSet<OrderRowModel> DbSetOrderRow { get; set; }
public virtual DbSet<ResourceModel> DbSetResource { get; set; }
public virtual DbSet<PhaseModel> DbSetPhase { get; set; }
public virtual DbSet<CostDriverModel> DbSetCostDriver { get; set; }
public virtual DbSet<JobTaskModel> DbSetJobTask { get; set; }
public virtual DbSet<JobStepModel> DbSetJobStep { get; set; }
public virtual DbSet<JobStepItemModel> DbSetJobStepItem { get; set; }
public virtual DbSet<ProductionItemModel> DbSetProdItem { get; set; }
public virtual DbSet<StockStatusModel> DbSetStockStatus { get; set; }
public virtual DbSet<MovTypeModel> DbSetMovType { get; set; }
public virtual DbSet<StockMovModel> DbSetStockMov { get; set; }
public virtual DbSet<GenClassModel> DbSetGenClass { get; set; }
public virtual DbSet<GenValueModel> DbSetGenVal { get; set; }
public virtual DbSet<StatsDetailModel> DbSetStatsDet { get; set; }
public virtual DbSet<StatsAggregatedModel> DbSetStatsAggr { get; set; }
public virtual DbSet<ProductionGroupModel> DbSetProdGroup { get; set; }
public virtual DbSet<ProductionPlantModel> DbSetProdPlant { get; set; }
public virtual DbSet<ProductionBatchModel> DbSetProdBatch { get; set; }
public virtual DbSet<ProductionODLModel> DbSetProdODL { get; set; }
public virtual DbSet<ProductionItem2ODLModel> DbSetProdItem2ODL { get; set; }
public virtual DbSet<TemplateModel> DbSetTemplate { get; set; }
public virtual DbSet<TemplateRowModel> DbSetTemplateRow { get; set; }
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// default
string connString = DbConfig.CONNECTION_STRING;
if (string.IsNullOrEmpty(connString))
{
#if DEBUG
connString = "Server=mdb.ufficio;port=3306;database=Lux_000;uid=lux_user;pwd=Egal_pwd!;sslmode=None;";
//connString = "Server=mdb.ufficio;port=3306;database=Lux_000_dev;uid=lux_user;pwd=Egal_pwd!;sslmode=None;";
#else
connString = "Server=mdb.ufficio;port=3306;database=Lux_000;uid=lux_user;pwd=Egal_pwd!;sslmode=None;";
#endif
}
if (!optionsBuilder.IsConfigured)
{
var serverVersion = ServerVersion.AutoDetect(connString);
// 2026.01.09 aggiornata init componente POMELO
#if false
optionsBuilder.UseMySql(connString, serverVersion);
#endif
optionsBuilder.UseMySql(connString, serverVersion, options =>
{
// Questo abilita il supporto JSON specifico per MySQL
options.EnableStringComparisonTranslations();
});
// verificare setup componente
#if false
optionsBuilder
.UseMySql(connString, serverVersion)
.UseSnakeCaseNamingConvention(); // via EFCore.NamingConventions
#endif
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
{
relationship.DeleteBehavior = DeleteBehavior.Restrict;
}
// fix key multiple
modelBuilder.Entity<JobTaskTagModel>()
.HasKey(jtt => new { jtt.JobID, jtt.CodTag });
modelBuilder.Entity<JobStepTagModel>()
.HasKey(jst => new { jst.JobStepID, jst.CodTag });
modelBuilder.Entity<ProductionItem2ODLModel>()
.HasKey(x => new { x.ProdItemID, x.ProdODLID });
modelBuilder.Entity<ProductionItem2ODLModel>()
.HasOne(x => x.ProductionItemNav)
.WithMany(i => i.Item2OdlNav)
.HasForeignKey(x => x.ProdItemID)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<ProductionItem2ODLModel>()
.HasOne(x => x.ProductionODLNav)
.WithMany(o => o.Item2OdlNav)
.HasForeignKey(x => x.ProdODLID)
.OnDelete(DeleteBehavior.Restrict);
// gestione dati DTX calcolati nel DB
#if false
modelBuilder.Entity<ProductionItemModel>()
.Property(p => p.ProdLabel)
// Utilizziamo la sintassi SQL di MySQL per la generazione del valore
// HEX(ProdItemID) trasforma l'ID in esadecimale, LPAD aggiunge gli zeri a sinistra
.HasComputedColumnSql("CONCAT('PT', LPAD(HEX(ProdItemID), 8, '0'))", stored: true);
#endif
modelBuilder.Entity<ProductionItemModel>()
.Property(p => p.ProdItemTag)
.IsRequired(false); // Permette l'inserimento iniziale nullo/vuoto
modelBuilder.Entity<ProductionItemModel>()
.HasIndex(x => new { x.ProdItemTag })
.HasDatabaseName("idx_prod_item_tag")
.IsUnique();
// gestione deserializzazione smart x oggetti con liste implicite
#if false
modelBuilder.Entity<ProductionAssignModel>()
.Property(e => e.TagList)
.HasConversion(
v => JsonConvert.SerializeObject(v), // Da List a String (per il DB)
v => JsonConvert.DeserializeObject<List<string>>(v) ?? new List<string>(), // Da String a List (per C#)
new ValueComparer<List<string>>( // Fondamentale per il tracking delle modifiche!
(c1, c2) => c1.SequenceEqual(c2),
c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
c => c.ToList()));
#endif
// FixMe ToDo da rivedere: valutare x altri casi!!!! non pare essere formulazione migliore ma la successiva
#if false
modelBuilder.Entity<ProductionAssignModel>()
.Property(e => e.TagList)
.HasColumnType("json");
#endif
// modalità non valida x Pomelo 8 e MariaDb
#if false
// gestione dei dati serializzati di stima tempi come JSON
modelBuilder.Entity<ProductionGroupModel>()
.OwnsMany(x => x.WorkGroupList, b =>
{
b.ToJson();
});
#endif
#if false
// JobTask ↔ Tags
modelBuilder.Entity<JobTaskTagModel>()
.HasOne(j => j.JobTaskNav)
.WithMany(t => t.TagNav)
.HasForeignKey(j => j.JobID);
modelBuilder.Entity<JobTaskTagModel>()
.HasOne(j => j.TagNav)
.WithMany(t => t.JobTaskNav)
.HasForeignKey(j => j.cod);
// JobStep ↔ Tags
modelBuilder.Entity<JobStepTagModel>()
.HasMany(js => js.TagNav)
.WithMany(t => t.JobSteps)
.UsingEntity(j => j.ToTable("JobStepTags"));
#endif
// fix chiavi multiple
modelBuilder.Entity<CounterModel>()
.HasKey(c => new { c.RefYear, c.CountName });
modelBuilder.Entity<GlassModel>()
.HasKey(c => new { c.GlassID });
modelBuilder.Entity<ProfileModel>()
.HasKey(c => new { c.ProfileID });
modelBuilder.Entity<WoodModel>()
.HasKey(c => new { c.WoodID });
// fix valori timestamp
modelBuilder.Entity<StockMovModel>(entity =>
{
entity.Property(e => e.DtCreate)
.HasColumnType("timestamp")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.ValueGeneratedOnAdd();
entity.Property(e => e.DtMod)
.HasColumnType("timestamp")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.ValueGeneratedOnAddOrUpdate();
});
// indici tabelle stats
modelBuilder.Entity<StatsDetailModel>()
.HasIndex(x => new { x.Hour, x.Environment, x.Type })
.HasDatabaseName("idx_statsdet_hour_env_type")
.IsUnique();
modelBuilder.Entity<StatsAggregatedModel>()
.HasIndex(x => new { x.Hour })
.HasDatabaseName("idx_statsaggr_hour")
.IsUnique();
// seed finale dei dati di default
modelBuilder.Seed();
OnModelCreatingPartial(modelBuilder);
}
public void DbForceMigrate()
{
try
{
// se non ci fosse... crea o migra!
Database.Migrate();
Log.Info("DbForceMigrate: done!");
}
catch (Exception exc)
{
Log.Error(exc, "DbForceMigrate: Exception during context initialization 01");
}
}
}
}