diff --git a/.vs/ApiManutenzioni/v17/.wsuo b/.vs/ApiManutenzioni/v17/.wsuo index 20c480e..26f2235 100644 Binary files a/.vs/ApiManutenzioni/v17/.wsuo and b/.vs/ApiManutenzioni/v17/.wsuo differ diff --git a/.vs/ApiPolo/DesignTimeBuild/.dtbcache.v2 b/.vs/ApiPolo/DesignTimeBuild/.dtbcache.v2 index 271f2d5..ee91b61 100644 Binary files a/.vs/ApiPolo/DesignTimeBuild/.dtbcache.v2 and b/.vs/ApiPolo/DesignTimeBuild/.dtbcache.v2 differ diff --git a/.vs/ProjectEvaluation/apipolo.metadata.v7.bin b/.vs/ProjectEvaluation/apipolo.metadata.v7.bin deleted file mode 100644 index de27bcb..0000000 Binary files a/.vs/ProjectEvaluation/apipolo.metadata.v7.bin and /dev/null differ diff --git a/.vs/ProjectEvaluation/apipolo.projects.v7.bin b/.vs/ProjectEvaluation/apipolo.projects.v7.bin deleted file mode 100644 index 585efd5..0000000 Binary files a/.vs/ProjectEvaluation/apipolo.projects.v7.bin and /dev/null differ diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json index 6b61141..29e7109 100644 --- a/.vs/VSWorkspaceState.json +++ b/.vs/VSWorkspaceState.json @@ -2,5 +2,6 @@ "ExpandedNodes": [ "" ], + "SelectedNode": "\\ApiPolo.sln", "PreviewInSolutionExplorer": false } \ No newline at end of file diff --git a/ApiPolo/Controllers/PoloController.cs b/ApiPolo/Controllers/PoloController.cs index 945703a..c5911e4 100644 --- a/ApiPolo/Controllers/PoloController.cs +++ b/ApiPolo/Controllers/PoloController.cs @@ -53,7 +53,7 @@ using Microsoft.Extensions.Primitives; using System.Text.RegularExpressions; using System.Runtime.CompilerServices; using System.Diagnostics; -using ApiPolo.Models.Maras_DbContext; +using ApiPolo.Data; namespace ApiPolo.Controllers { @@ -2999,6 +2999,9 @@ namespace ApiPolo.Controllers /// Syscom public const string Syscom = "A0001"; + /// Syscom + public const string Maras = "MARAS"; + } /// public static class suffClienti diff --git a/ApiPolo/Controllers/TestController.cs b/ApiPolo/Controllers/TestController.cs new file mode 100644 index 0000000..c314ba1 --- /dev/null +++ b/ApiPolo/Controllers/TestController.cs @@ -0,0 +1,137 @@ +using ApiPolo.Interfaces; +using ApiPolo.Models; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace ApiPolo.Controllers +{ + public class TestController : Controller + { + //interfaccia con tutti i possibili dbset + private readonly ITenantDbContextFactory _dbContextFactory; + //DI con ITenantDbContextFactory + public TestController(ITenantDbContextFactory dbContextFactory) + { + _dbContextFactory = dbContextFactory; + } + + //ATTENZIONE - CONFLITTO TRA Compo_Impia_Table e + + #region GET_BY_TENANT + private DbSet getTecniciByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Tecnici; // Use Set() to handle different DbContexts + } + private DbSet getRappNewByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Rapps; // Use Set() to handle different DbContexts + } + private DbSet getChiamateByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Chiamate; // Use Set() to handle different DbContexts + } + private DbSet? getChiusureByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Chiusure; + } + private DbSet getManutenzioniByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Manutenzioni; // Use Set() to handle different DbContexts + } + private DbSet getPreseByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Prese; // Use Set() to handle different DbContexts + } + private DbSet getSto_RappByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.StoRapp; // Use Set() to handle different DbContexts + } + private DbSet getClientiByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Clienti; // Use Set() to handle different DbContexts + } + private DbSet getCausaliRappByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Causali; // Use Set() to handle different DbContexts + } + private DbSet getPagamentiByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Pagamenti; // Use Set() to handle different DbContexts + } + + private DbSet getSaldiartByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Saldi; // Use Set() to handle different DbContexts + } + /// + /// CONFLITTO CON Compo_Impia_Table + /// + /* + private DbSet getComponentiByTenant(string tenant) + { // IN CONFLITTO CON Compo_Impia_Table + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Componen; // Use Set() to handle different DbContexts + }*/ + private DbSet getComponentiTableByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Componen; // Use Set() to handle different DbContexts + } + private DbSet getMagazziniByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Magaz; // Use Set() to handle different DbContexts + } + private DbSet getMag_NewByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Mag; // Use Set() to handle different DbContexts + } + private DbSet getImpiantiByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Impia; // Use Set() to handle different DbContexts + } + private DbSet getCommesseByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Commesse; // Use Set() to handle different DbContexts + } + private DbSet getTimbratureByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Timbr; // Use Set() to handle different DbContexts + } + + private DbSet getStoricoImpiantoByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.StoImp; // Use Set() to handle different DbContexts + } + private DbSet getAziendeRifByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Azi; // Use Set() to handle different DbContexts + } + private DbSet getSostituzioneByTenant(string tenant) + { + var dbContext = _dbContextFactory.GetDbContext(tenant); + return dbContext.Sost; // Use Set() to handle different DbContexts + } + #endregion + + } + + +} diff --git a/ApiPolo/Data/Maras_DbContext.cs b/ApiPolo/Data/Maras_DbContext.cs new file mode 100644 index 0000000..7c67cfb --- /dev/null +++ b/ApiPolo/Data/Maras_DbContext.cs @@ -0,0 +1,171 @@ +using ApiPolo.Interfaces; +using ApiPolo.Models; +using Microsoft.EntityFrameworkCore; + +namespace ApiPolo.Data +{ + public class Maras_DbContext : DbContext,ITenantDbContext + { + #region PROPERTIES + public DbSet? Causali { get; set; } + + public DbSet? Chiusure { get; set; } + + public DbSet? Azi { get; set; } + + public DbSet? ccci { get; set; } + + public DbSet? ccciWiev { get; set; } + + public DbSet? Chiamate { get; set; } + + public DbSet? Clienti { get; set; } + + public DbSet? Componen { get; set; } // IN CONFLITTO CON Compo_Impia + + //public DbSet? Componen { get; set; } //CAMBIARE NOME!!! + + public DbSet? Impia { get; set; } + + public DbSet? Mag { get; set; } + + public DbSet? Magaz { get; set; } + + public DbSet? Manutenzioni { get; set; } + + public DbSet? Pagamenti { get; set; } + + public DbSet? Prese { get; set; } + + public DbSet? Rapps { get; set; } + + public DbSet? rapp { get; set; } + + public DbSet? Sost { get; set; } + + public DbSet? Saldi { get; set; } + + public DbSet? StoRapp { get; set; } + + public DbSet? Tecnici { get; set; } + public DbSet? StoImp { get; set; } + + public DbSet? Timbr { get; set; } + + public DbSet? Commesse { get; set; } + #endregion + + + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + + void TryConfigureEntity(Action configure, string entityName) + { + try + { + configure(modelBuilder); + } + catch (Exception ex) + { + Console.WriteLine($"Warning: Skipping entity '{entityName}' due to error: {ex.Message}"); + } + } + + TryConfigureEntity(mb => mb.Entity().ToView("API_CAUS_RAPP"), "API_CAUS_RAPP"); + + TryConfigureEntity(mb => mb.Entity().ToView("API_CHIUSURE"), "API_CHIUSURE"); + + TryConfigureEntity(mb => + { + mb.Entity().ToTable("PIAZIRIF"); + mb.Entity().HasKey(table => new + { + table.piazihoc, + table.picodtec, + table.pirifazi + }); + }, "PIAZIRIF"); + + TryConfigureEntity(mb => + { + mb.Entity().ToTable("PIASSCHIU"); + mb.Entity().HasKey(table => new + { + table.picodazi, + table.picodint, + table.picodchi + }); + }, "PIASSCHIU"); + + TryConfigureEntity(mb => mb.Entity().ToView("API_ASSCHIU"), "API_ASSCHIU"); + + TryConfigureEntity(mb => mb.Entity().ToView("API_CHIAMATE"), "API_CHIAMATE"); + + TryConfigureEntity(mb => mb.Entity().ToView("API_CLIENTI"), "API_CLIENTI"); + + TryConfigureEntity(mb => + { + mb.Entity().ToTable("DISCOMICOMIMP"); + mb.Entity().HasKey(table => new + { + table.cocodimp, + table.cprownum, + table.cocodazi + }); + }, "DISCOMICOMIMP"); + + TryConfigureEntity(mb => mb.Entity().ToView("API_MICOMIMP"), "API_MICOMIMP"); + + TryConfigureEntity(mb => mb.Entity().ToView("API_IMPIANTI"), "API_IMPIANTI"); + + TryConfigureEntity(mb => + { + mb.Entity().ToTable("DISCOMAG_NEW"); + mb.Entity().HasKey(table => new + { + table.seriale_rapportino, + table.riga + }); + }, "DISCOMAG_NEW"); + + TryConfigureEntity(mb => mb.Entity().ToTable("DISCOMAGAZZIN"), "DISCOMAGAZZIN"); + + TryConfigureEntity(mb => mb.Entity().ToView("API_MANPROG"), "API_MANPROG"); + + TryConfigureEntity(mb => mb.Entity().ToView("API_PAGAMENTI"), "API_PAGAMENTI"); + + TryConfigureEntity(mb => + { + mb.Entity().ToTable("PIPRESA"); + mb.Entity().HasKey(table => new + { + table.picodazi, + table.pimpianto, + table.picodint, + table.pidatman + }); + }, "PIPRESA"); + + TryConfigureEntity(mb => mb.Entity().ToTable("RAPP_NEW"), "RAPP_NEW"); + + TryConfigureEntity(mb => mb.Entity().ToView("API_RAPPORTINI"), "API_RAPPORTINI"); + + TryConfigureEntity(mb => mb.Entity().ToView("API_SALDIART_PREZZI"), "API_SALDIART_PREZZI"); + + TryConfigureEntity(mb => mb.Entity().ToView("API_SOSTITUZIONI"), "API_SOSTITUZIONI"); + + TryConfigureEntity(mb => mb.Entity().ToView("API_STO_RAPP"), "API_STO_RAPP"); + + TryConfigureEntity(mb => mb.Entity().ToView("API_TECNICI"), "API_TECNICI"); + + TryConfigureEntity(mb => mb.Entity().ToTable("TIMBRATURE"), "TIMBRATURE"); + + TryConfigureEntity(mb => mb.Entity().ToView("API_COMMESSE"), "API_COMMESSE"); + + TryConfigureEntity(mb => mb.Entity().ToView("API_STO_IMP"), "API_STO_IMP"); + + + } + } +} diff --git a/ApiPolo/Interfaces/ITenantDbContext.cs b/ApiPolo/Interfaces/ITenantDbContext.cs new file mode 100644 index 0000000..c4025ab --- /dev/null +++ b/ApiPolo/Interfaces/ITenantDbContext.cs @@ -0,0 +1,32 @@ +using Microsoft.EntityFrameworkCore; +using ApiPolo.Models; + +namespace ApiPolo.Interfaces +{ + public interface ITenantDbContext + { + DbSet? Causali { get; set; } + DbSet? Commesse { get; set; } + DbSet? Chiusure { get; set; } + DbSet? Azi { get; set; } + DbSet? ccci { get; set; } + DbSet? ccciWiev { get; set; } + DbSet? Chiamate { get; set; } + DbSet? Clienti { get; set; } + DbSet? Componen { get; set; } + DbSet? Impia { get; set; } + DbSet? Mag { get; set; } + DbSet? Magaz { get; set; } + DbSet? Manutenzioni { get; set; } + DbSet? Pagamenti { get; set; } + DbSet? Prese { get; set; } + DbSet? Rapps { get; set; } + DbSet? rapp { get; set; } + DbSet? Sost { get; set; } + DbSet? Saldi { get; set; } + DbSet? StoRapp { get; set; } + DbSet? Tecnici { get; set; } + DbSet? Timbr { get; set; } + DbSet? StoImp { get; set; } + } +} diff --git a/ApiPolo/Interfaces/ITenantDbContextFactory.cs b/ApiPolo/Interfaces/ITenantDbContextFactory.cs new file mode 100644 index 0000000..f5054e1 --- /dev/null +++ b/ApiPolo/Interfaces/ITenantDbContextFactory.cs @@ -0,0 +1,9 @@ +using Microsoft.EntityFrameworkCore; + +namespace ApiPolo.Interfaces +{ + public interface ITenantDbContextFactory + { + ITenantDbContext GetDbContext(string tenant); + } +} diff --git a/ApiPolo/Interfaces/TenantDbContextFactory.cs b/ApiPolo/Interfaces/TenantDbContextFactory.cs new file mode 100644 index 0000000..1c18d20 --- /dev/null +++ b/ApiPolo/Interfaces/TenantDbContextFactory.cs @@ -0,0 +1,31 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using ApiPolo.Interfaces; +using System; +using System.Collections.Generic; +using static ApiPolo.Controllers.PoloController; +using ApiPolo.Data; + +namespace ApiPolo.Services +{ + public class TenantDbContextFactory : ITenantDbContextFactory + { + private readonly IServiceProvider _serviceProvider; + + public TenantDbContextFactory(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public ITenantDbContext GetDbContext(string tenant) + { + return tenant switch + { + Clienti.Maras => _serviceProvider.GetRequiredService(), + // Add other tenants as needed + // Clienti.AnotherTenant => _serviceProvider.GetRequiredService(), + _ => throw new KeyNotFoundException($"No DbContext found for tenant: {tenant}") + }; + } + } +} diff --git a/ApiPolo/Models/Maras_DbContext/Maras_DbContext.cs b/ApiPolo/Models/Maras_DbContext/Maras_DbContext.cs deleted file mode 100644 index 814510a..0000000 --- a/ApiPolo/Models/Maras_DbContext/Maras_DbContext.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Microsoft.EntityFrameworkCore; - -namespace ApiPolo.Models.Maras_DbContext -{ - public class Maras_DbContext : DbContext - { - public DbSet? Causali { get; set; } - public DbSet? Chiusure { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity().ToView("API_CAUS_RAPP"); - modelBuilder.Entity().ToView("API_CHIUSURE"); - } - } -} diff --git a/ApiPolo/Startup.cs b/ApiPolo/Startup.cs index 20d2a89..9e7c94b 100644 --- a/ApiPolo/Startup.cs +++ b/ApiPolo/Startup.cs @@ -16,6 +16,8 @@ using ApiPolo.Models.VT_dbcontext; using ApiPolo.Models.Tedesco_dbcontext; using ApiPolo.Models.Lift_web_dbcontext; using ApiPolo.Models.Security_dbcontext; +using ApiPolo.Interfaces; +using ApiPolo.Data; namespace ApiPolo { @@ -1013,6 +1015,13 @@ namespace ApiPolo )); #endregion + services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("MARAS") + , options => { options.CommandTimeout(commandTimeoutInSeconds); } + )); + + // FACTORY MUTI-TENANT + services.AddSingleton(); + services.AddSwaggerGen(gen => { diff --git a/ApiPolo/appsettings.json b/ApiPolo/appsettings.json index 3281992..889cc17 100644 --- a/ApiPolo/appsettings.json +++ b/ApiPolo/appsettings.json @@ -55,7 +55,9 @@ /*"SYSCOM": "Data Source=docker1.polo;Initial Catalog= AHRW_SYSCOM;User Id=sa; Password=p0l01nf.;Integrated Security=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",*/ "SYSCOM": "Data Source=dbsql01.poloinformatico.it;Initial Catalog= AHRW_SYSCOM;User Id=syscom; Password=4@QLHV?cpVYbr+GB;Integrated Security=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False", - "TEDESCO": "Data Source=MARCO_PC\\SQL_2022;Initial Catalog= AHR_TEDESCO;User Id=sa; Password=p0l01nf.;Integrated Security=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False" + "TEDESCO": "Data Source=MARCO_PC\\SQL_2022;Initial Catalog= AHR_TEDESCO;User Id=sa; Password=p0l01nf.;Integrated Security=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False", + + "MARAS": "Data Source=docker1.polo;Initial Catalog= AHRW_MARAS;User Id=sa; Password=p0l01nf.;Integrated Security=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False;Encrypt=False" }, "JWT": { "ValidAudience": "http://localhost:4200",