04f0403f12
BREAKING CHANGE: Rimosso completamente il vecchio sistema RecordAssociation Modifiche principali: - Sostituito RecordAssociation con KeyAssociation basato sui valori delle chiavi - Implementata logica robusta di UPDATE vs INSERT basata su associazioni esistenti - Aggiunta normalizzazione delle chiavi (.Trim()) per consistenza - Implementato fallback nella ricerca associazioni per maggiore affidabilità - Sostituita verifica pre-UPDATE con tentativo diretto più efficiente Componenti modificati: - Nuovo modello: KeyAssociation.cs con campi ottimizzati - Nuovo servizio: KeyAssociationService.cs con metodi completi - Aggiornato: DataCoupler.razor con logica migliorata di gestione associazioni - Aggiornato: CredentialDbContext per gestire solo KeyAssociations - Aggiornati: tutti i servizi di interfaccia per supportare il nuovo sistema - Creata: pagina KeyAssociations.razor per gestione associazioni - Aggiornato: NavMenu.razor con link alla gestione associazioni Miglioramenti tecnici: - Logica di UPDATE più robusta: tenta direttamente l'aggiornamento invece di verificare prima l'esistenza - Gestione errori migliorata con cleanup automatico delle associazioni non valide - Debug logging estensivo per troubleshooting - Fallback nella ricerca associazioni se parametri specifici falliscono - Normalizzazione valori chiave per prevenire problemi di whitespace Risultato: Il sistema ora previene correttamente i duplicati utilizzando le associazioni per decidere se fare INSERT (nuovo record) o UPDATE (record esistente) basandosi sui valori delle chiavi. Database: - Creata migrazione EF per rimuovere RecordAssociations e aggiungere KeyAssociations - Eliminati file e codice legacy non più necessari
92 lines
2.6 KiB
C#
92 lines
2.6 KiB
C#
using System.ComponentModel.DataAnnotations;
|
|
|
|
namespace CredentialManager.Models;
|
|
|
|
/// <summary>
|
|
/// Entità per memorizzare le associazioni basate sui valori delle chiavi
|
|
/// Un'associazione lega un valore di chiave a un record di destinazione,
|
|
/// indipendentemente dalla sorgente che ha generato quel valore
|
|
/// </summary>
|
|
public class KeyAssociation
|
|
{
|
|
[Key]
|
|
public int Id { get; set; }
|
|
|
|
/// <summary>
|
|
/// Valore della chiave che identifica univocamente l'oggetto business
|
|
/// (es: "CUST001", "12345", "ABC-DEF-GHI")
|
|
/// </summary>
|
|
[Required]
|
|
[MaxLength(500)]
|
|
public string KeyValue { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// Nome del campo chiave nella sorgente
|
|
/// (es: "CustomerCode", "ID", "ArticleNumber")
|
|
/// </summary>
|
|
[Required]
|
|
[MaxLength(200)]
|
|
public string SourceKeyField { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// Nome del campo chiave nella destinazione
|
|
/// (es: "CardCode", "DocEntry", "ItemCode")
|
|
/// </summary>
|
|
[Required]
|
|
[MaxLength(200)]
|
|
public string DestinationKeyField { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// Nome dell'entità di destinazione
|
|
/// </summary>
|
|
[Required]
|
|
[MaxLength(200)]
|
|
public string DestinationEntity { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// ID del record di destinazione
|
|
/// </summary>
|
|
[Required]
|
|
[MaxLength(200)]
|
|
public string DestinationId { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// Nome della credenziale REST utilizzata per la destinazione
|
|
/// </summary>
|
|
[Required]
|
|
[MaxLength(100)]
|
|
public string RestCredentialName { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// Data e ora della creazione dell'associazione
|
|
/// </summary>
|
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
|
|
|
/// <summary>
|
|
/// Data e ora dell'ultimo aggiornamento
|
|
/// </summary>
|
|
public DateTime? UpdatedAt { get; set; }
|
|
|
|
/// <summary>
|
|
/// Data e ora dell'ultima verifica che il record di destinazione esiste ancora
|
|
/// </summary>
|
|
public DateTime? LastVerifiedAt { get; set; }
|
|
|
|
/// <summary>
|
|
/// Indica se l'associazione è ancora attiva
|
|
/// </summary>
|
|
public bool IsActive { get; set; } = true;
|
|
|
|
/// <summary>
|
|
/// Informazioni aggiuntive sui record che hanno contribuito a questa associazione
|
|
/// </summary>
|
|
[MaxLength(2000)]
|
|
public string? SourcesInfo { get; set; }
|
|
|
|
/// <summary>
|
|
/// Informazioni aggiuntive in formato JSON
|
|
/// </summary>
|
|
[MaxLength(2000)]
|
|
public string? AdditionalInfo { get; set; }
|
|
}
|