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
@@ -109,6 +109,7 @@ public class DataCouplerProfileService : IDataCouplerProfileService
existingProfile.DestinationTable = profile.DestinationTable;
existingProfile.DestinationEndpoint = profile.DestinationEndpoint;
existingProfile.FieldMappingJson = profile.FieldMappingJson;
existingProfile.ExternalIdRelationshipsJson = profile.ExternalIdRelationshipsJson;
existingProfile.SourceKeyField = profile.SourceKeyField;
existingProfile.UseRecordAssociations = profile.UseRecordAssociations;
existingProfile.IsActive = profile.IsActive;
@@ -200,6 +201,41 @@ public class DataCouplerProfileService : IDataCouplerProfileService
return new List<FieldMappingDto>();
}
}
/// <summary>
/// Serializza la lista di External ID Relationships in JSON
/// </summary>
public string SerializeExternalIdRelationships(List<ExternalIdRelationshipDto>? relationships)
{
if (relationships == null || !relationships.Any())
return string.Empty;
return JsonSerializer.Serialize(relationships, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
});
}
/// <summary>
/// Deserializza il JSON delle External ID Relationships
/// </summary>
public List<ExternalIdRelationshipDto> DeserializeExternalIdRelationships(string? json)
{
if (string.IsNullOrWhiteSpace(json))
return new List<ExternalIdRelationshipDto>();
try
{
return JsonSerializer.Deserialize<List<ExternalIdRelationshipDto>>(json, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
}) ?? new List<ExternalIdRelationshipDto>();
}
catch
{
return new List<ExternalIdRelationshipDto>();
}
}
/// <summary>
/// Converte un DataCouplerProfile in DTO
@@ -226,6 +262,7 @@ public class DataCouplerProfileService : IDataCouplerProfileService
DestinationTable = profile.DestinationTable,
DestinationEndpoint = profile.DestinationEndpoint,
FieldMappings = DeserializeFieldMappings(profile.FieldMappingJson),
ExternalIdRelationships = DeserializeExternalIdRelationships(profile.ExternalIdRelationshipsJson),
SourceKeyField = profile.SourceKeyField,
UseRecordAssociations = profile.UseRecordAssociations
};
@@ -254,6 +291,7 @@ public class DataCouplerProfileService : IDataCouplerProfileService
DestinationTable = dto.DestinationTable,
DestinationEndpoint = dto.DestinationEndpoint,
FieldMappingJson = SerializeFieldMappings(dto.FieldMappings),
ExternalIdRelationshipsJson = SerializeExternalIdRelationships(dto.ExternalIdRelationships),
SourceKeyField = dto.SourceKeyField,
UseRecordAssociations = dto.UseRecordAssociations,
CreatedBy = createdBy