Fix: Risolto double-mapping negli External ID Relationships per Salesforce

- Implementata funzionalità completa External ID Relationships nell'interfaccia di mapping
- Corretto bug double-mapping: i campi sorgente usati per External ID non vengono più inclusi nei mapping normali
- Risolto errore MALFORMED_ID causato dall'invio duplicato di campi come proprietà dirette e nested objects
- Implementata logica corretta per relationship names: oggetti standard usano il nome diretto, custom objects usano suffisso __r
- Aggiunta UI a 3 colonne (Object, External ID Field, Source Field) per configurazione External ID Relationships
- Migrazione database per supporto External ID Relationships nei profili
- Aggiornato ProfileSaver.razor.cs per salvare/caricare External ID Relationships
- Aggiornato ScheduledProfileExecutionService.cs per gestire External ID nelle esecuzioni schedulate
- Formato JSON output corretto: { 'Account': { 'CardCode__c': 'V50000' } }

Documentazione: EXTERNAL_ID_RELATIONSHIPS_IMPLEMENTATION.md
This commit is contained in:
2026-02-15 18:44:15 +01:00
parent ed5316fbdf
commit 483eb7b407
16 changed files with 1923 additions and 21 deletions
+48 -5
View File
@@ -474,12 +474,27 @@ else
<label class="form-label">Host/Server *</label>
<InputText class="form-control" @bind-Value="currentDatabaseCredential.Host"
placeholder="es. localhost o server.dominio.com" />
@if (currentDatabaseCredential.DatabaseType == DatabaseType.SqlServer)
{
<div class="form-text">
<strong>SQL Server locale:</strong><br/>
• Named Instance: <code>localhost\SQLEXPRESS</code> o <code>.\SQLEXPRESS</code><br/>
• LocalDB: <code>(localdb)\MSSQLLocalDB</code><br/>
• Default: <code>localhost</code> o <code>.</code> (usa porta 1433)
</div>
}
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label class="form-label">Porta *</label>
<InputNumber class="form-control" @bind-Value="currentDatabaseCredential.Port" />
@if (currentDatabaseCredential.DatabaseType == DatabaseType.SqlServer)
{
<div class="form-text">
<small>Ignorata per named instances e LocalDB</small>
</div>
}
</div>
</div>
</div>
@@ -495,13 +510,26 @@ else
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Username *</label>
<InputText class="form-control" @bind-Value="currentDatabaseCredential.Username" />
<InputText class="form-control" @bind-Value="currentDatabaseCredential.Username"
placeholder="o scrivi 'Integrated' per Windows Auth" />
@if (currentDatabaseCredential.DatabaseType == DatabaseType.SqlServer)
{
<div class="form-text">
<small>Per Windows Authentication, scrivi <strong>Integrated</strong> o lascia vuoto</small>
</div>
}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Password *</label>
<InputText type="password" class="form-control" @bind-Value="currentDatabaseCredential.Password" />
@if (currentDatabaseCredential.DatabaseType == DatabaseType.SqlServer)
{
<div class="form-text">
<small>Non richiesta per Windows Authentication</small>
</div>
}
</div>
</div>
</div>
@@ -994,13 +1022,28 @@ else
else
{
// Altri database: validazione standard (Host, Username, Password)
if (string.IsNullOrEmpty(currentDatabaseCredential.Host) ||
string.IsNullOrEmpty(currentDatabaseCredential.Username) ||
string.IsNullOrEmpty(currentDatabaseCredential.Password))
// Per SQL Server, permetti Windows Authentication (username vuoto o "Integrated")
bool isSqlServerWithWindowsAuth = currentDatabaseCredential.DatabaseType == DatabaseType.SqlServer &&
(string.IsNullOrWhiteSpace(currentDatabaseCredential.Username) ||
currentDatabaseCredential.Username.Equals("Integrated", StringComparison.OrdinalIgnoreCase) ||
currentDatabaseCredential.Username.Equals("Windows", StringComparison.OrdinalIgnoreCase));
if (string.IsNullOrEmpty(currentDatabaseCredential.Host))
{
await JSRuntime.InvokeVoidAsync("alert", "Compila tutti i campi obbligatori (Host, Username, Password).");
await JSRuntime.InvokeVoidAsync("alert", "Il campo Host è obbligatorio.");
return;
}
if (!isSqlServerWithWindowsAuth)
{
// Per database che non usano Windows Authentication, richiedi username e password
if (string.IsNullOrEmpty(currentDatabaseCredential.Username) ||
string.IsNullOrEmpty(currentDatabaseCredential.Password))
{
await JSRuntime.InvokeVoidAsync("alert", "Username e Password sono obbligatori. Per SQL Server con Windows Authentication, inserisci 'Integrated' come username.");
return;
}
}
}
var (success, message) = await CredentialService.TestDatabaseConnectionAsync(currentDatabaseCredential);