- Aggiunto campo MappedDestinationField al modello KeyAssociation per tracciare il campo destinazione mappato alla chiave sorgente
- Creata migration AddMappedDestinationFieldToKeyAssociation per aggiungere la colonna al database
- Implementata logica di popolamento in CreateAssociationAsync e StartDataTransferOriginal per salvare il campo destinazione mappato
- Aggiornato SaveAssociationParallelAsync per includere MappedDestinationField nelle query SQL UPDATE e INSERT
- Corretti indici parametri nella query UPDATE (da {7-9} a {8-10}) per includere il nuovo campo
- Aggiunta visualizzazione campo nell'interfaccia KeyAssociations (tabella, dettagli, export CSV)
- Implementato controllo validazione per impedire trasferimenti se il campo chiave non è mappato
- Aggiunto logging diagnostico dettagliato per debug del mapping dei campi
- Aggiornato ScheduledProfileExecutionService per popolare MappedDestinationField nelle esecuzioni schedulate
- Rimosso file BackgroundServices.cs obsoleto
- Documentazione completa creata (4 markdown files)
Fixes: Campo MappedDestinationField rimaneva NULL perché le query SQL raw non includevano il nuovo campo
6.3 KiB
Troubleshooting MappedDestinationField NULL
Data: 20 Ottobre 2025
Problema Segnalato
Il campo MappedDestinationField rimane sempre NULL nelle associazioni anche quando viene fatto un mapping.
Analisi del Problema
Come Dovrebbe Funzionare
- L'utente crea un mapping:
CardCode(sorgente) →cardcode__c(destinazione) - L'utente seleziona
CardCodecome campo chiave sorgente - Durante il trasferimento, il sistema dovrebbe:
- Cercare
CardCodenel dizionariofieldMappings - Trovare il valore mappato
cardcode__c - Salvarlo in
MappedDestinationField
- Cercare
Struttura Dati
// fieldMappings è un Dictionary<string, string>
// Chiave: nome colonna sorgente (es. "CardCode")
// Valore: nome campo destinazione (es. "cardcode__c")
Dictionary<string, string> fieldMappings = new()
{
{ "CardCode", "cardcode__c" },
{ "CardName", "Name" },
{ "City", "BillingCity" }
};
// sourceKeyField è la colonna selezionata come chiave
string sourceKeyField = "CardCode";
// Logica di ricerca
if (fieldMappings.ContainsKey(sourceKeyField))
{
mappedDestinationField = fieldMappings[sourceKeyField]; // Dovrebbe essere "cardcode__c"
}
Possibili Cause
1. Campo Chiave Non Mappato ❌
Scenario: L'utente seleziona un campo chiave che NON è stato mappato.
Esempio:
Mappings creati:
- CardName → Name
- City → BillingCity
Campo chiave selezionato: CardCode ← NON MAPPATO!
Risultato: MappedDestinationField = NULL
Soluzione: Verificare che il campo chiave selezionato sia presente nei mappings.
2. Case Sensitivity Issues ⚠️
Scenario: Il nome del campo chiave non corrisponde esattamente alla chiave nel dizionario.
Esempio:
Mapping creato: "cardcode" → "cardcode__c"
Campo chiave: "CardCode" ← Diverso per maiuscole!
Risultato: ContainsKey restituisce false
Soluzione: Verificare che il nome sia identico (case-sensitive).
3. Spazi o Caratteri Nascosti 🔍
Scenario: Presenza di spazi all'inizio/fine del nome campo.
Esempio:
Mapping: "CardCode " → "cardcode__c" (nota lo spazio finale)
Campo chiave: "CardCode"
Risultato: Non corrisponde
Soluzione: Trim dei nomi campo durante la creazione del mapping.
Logging Diagnostico Aggiunto
Ho aggiunto logging dettagliato per diagnosticare il problema:
Logger.LogDebug("MAPPING DEBUG: Tentativo di trovare mapping per sourceKeyField: '{SourceKeyField}'", sourceKeyField);
Logger.LogDebug("MAPPING DEBUG: Mappings disponibili: {Mappings}",
string.Join(", ", fieldMappings.Select(m => $"{m.Key} -> {m.Value}")));
if (fieldMappings.ContainsKey(sourceKeyField))
{
mappedDestinationField = fieldMappings[sourceKeyField];
Logger.LogDebug("MAPPING DEBUG: Trovato mapping: '{SourceKeyField}' -> '{MappedField}'",
sourceKeyField, mappedDestinationField);
}
else
{
Logger.LogWarning("MAPPING DEBUG: Campo chiave '{SourceKeyField}' NON trovato nei mappings!",
sourceKeyField);
}
Procedura di Diagnosi
Step 1: Abilitare Logging Debug
In appsettings.Development.json:
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"Data_Coupler.Pages.DataCoupler": "Debug"
}
}
}
Step 2: Eseguire un Trasferimento Dati
- Creare almeno un mapping che include il campo chiave
- Selezionare il campo chiave
- Eseguire il trasferimento
- Monitorare i log
Step 3: Analizzare i Log
Cercare le righe MAPPING DEBUG:
Caso 1: Campo Trovato ✅
[Debug] MAPPING DEBUG: Tentativo di trovare mapping per sourceKeyField: 'CardCode'
[Debug] MAPPING DEBUG: Mappings disponibili: CardCode -> cardcode__c, CardName -> Name
[Debug] MAPPING DEBUG: Trovato mapping: 'CardCode' -> 'cardcode__c'
[Info] COMPOSITE: Associazione creata con ID: 42 - MappedField: cardcode__c
Risultato: MappedDestinationField dovrebbe essere popolato correttamente.
Caso 2: Campo Non Trovato ❌
[Debug] MAPPING DEBUG: Tentativo di trovare mapping per sourceKeyField: 'CardCode'
[Debug] MAPPING DEBUG: Mappings disponibili: CardName -> Name, City -> BillingCity
[Warning] MAPPING DEBUG: Campo chiave 'CardCode' NON trovato nei mappings!
[Info] COMPOSITE: Associazione creata con ID: 42 - MappedField: N/A
Problema: Il campo chiave non è stato mappato!
Soluzione: Creare un mapping per il campo chiave.
Step 4: Verificare il Database
-- Verifica le associazioni create
SELECT
Id,
KeyValue,
SourceKeyField,
DestinationKeyField,
MappedDestinationField,
DestinationEntity,
CreatedAt
FROM KeyAssociations
ORDER BY CreatedAt DESC
LIMIT 10;
Cosa Cercare:
SourceKeyField: Dovrebbe essere il nome del campo chiave (es. "CardCode")MappedDestinationField:- Se NULL → il campo non era nei mappings
- Se valorizzato → tutto OK
Soluzione Temporanea
Se il problema persiste, puoi verificare manualmente nel database:
-- Trova associazioni senza campo mappato
SELECT COUNT(*)
FROM KeyAssociations
WHERE MappedDestinationField IS NULL;
-- Verifica un'associazione specifica
SELECT
KeyValue,
SourceKeyField,
MappedDestinationField,
AdditionalInfo
FROM KeyAssociations
WHERE Id = [ID_ASSOCIAZIONE];
Test Case
Per testare la funzionalità:
Test 1: Campo Mappato ✅
1. Crea mapping: CardCode → cardcode__c
2. Seleziona campo chiave: CardCode
3. Esegui trasferimento
4. Verifica: MappedDestinationField = "cardcode__c"
Test 2: Campo Non Mappato ❌
1. Crea mapping: CardName → Name (NON mappare CardCode)
2. Seleziona campo chiave: CardCode
3. Esegui trasferimento
4. Verifica: MappedDestinationField = NULL
5. Log: "Campo chiave 'CardCode' NON trovato nei mappings!"
Test 3: Controllo Validazione
Il sistema dovrebbe impedire il trasferimento se il campo chiave non è mappato (controllo aggiunto precedentemente).
Prossimi Passi
- Eseguire un test con logging abilitato
- Catturare i log durante il trasferimento
- Analizzare l'output del MAPPING DEBUG
- Determinare se il problema è:
- Campo non mappato (normale, warning utente)
- Bug nel codice di lookup (da fixare)
- Problema di encoding/spazi (sanitizzare input)
File Modificati
- ✅
Data_Coupler/Pages/DataCoupler.razor.cs- Aggiunto logging diagnostico
Status: 🔍 IN DIAGNOSI
Logging aggiunto, in attesa di eseguire test per identificare la causa esatta.