Come si calcola in modo efficiente la nuova proprietà per i vecchi record?

0

Diciamo che abbiamo classi come questa:

public class Item1{
    public Guid Id {get; set;}
    public string Name {get; set;}
    public decimal Price {get; set;}
    public int Quantity {get; set;}
}

E alcuni altri, che hanno campi aggiuntivi o diversi, altri hanno liste come proprietà.

E quelle classi vengono serializzate in stringhe Xml e posizionate come proprietà di un'altra classe, che verrà salvata nel database.

public class Record{
    public Guid Id {get; set;}
    public DateTime CreatedOn {get; set;}
    public string SerializedItem {get; set;}
}

Quando è necessario, estraiamo il record e deserializziamo in classe Item1 , Item2 o altro. Tutto è bello e bello.

Ma un giorno decidiamo che abbiamo bisogno di una proprietà aggiuntiva Discount . Se lo sconto Price * Quantity > 1000 sarebbe 10 per quell'elemento, se superiore a 5000 sconto 20 e così via. E useremmo quelle classi per mostrarle in una griglia (lista semplice), generare report e probabilmente come una variabile in classi (ad esempio se lo sconto è maggiore di 20 quella voce non potrebbe ottenere una spedizione gratuita o qualcosa del genere). Per non duplicare il calcolo di Discount , decidiamo di avere proprietà aggiuntive nella nostra classe Item1 come public decimal Discount {get; set;} , che viene calcolata durante l'inserimento di questo nuovo elemento.

Quindi ecco il problema che vediamo: quando deserializzando i vecchi articoli non avrebbero questa proprietà, quindi deserializzatore darebbe valori predefiniti come null , 0 , false a seconda del tipo di proprietà. Tuttavia, vogliamo che i vecchi articoli abbiano un valore Discount calcolato in base alla logica che vengono calcolati i nuovi articoli Discount .

Quindi come ottenerlo in modo efficiente? Sarebbe saggio avere un metodo che ricalcoli lo sconto (si noti che potrebbero esserci un paio di migliaia di elementi e la logica sarebbe più complicata) prima di dare questi elementi alla griglia, ai report e da qualche altra parte? O è più efficiente avere uno script che esegua il loop di tutti i record e calcoli lo sconto, ed eseguirlo una volta dopo l'aggiornamento alla nuova versione?

Qualche intuizione e suggerimento sono apprezzati. E fammi sapere o modificare se titolo e tag sono inappropriati o troppo vaghi.

    
posta Mantas Čekanauskas 27.05.2016 - 09:59
fonte

2 risposte

2

So how to achieve that efficiently?

È necessario memorizzare una versione dei dati serializzati. Dovresti anche scrivere una logica di migrazione nel tuo serializzatore in modo che, se incontra una vecchia versione dei dati, chiamerebbe data-migrator per questo dopo la deserializzazione.

Dopo la migrazione i dati dovrebbero essere salvati in un nuovo formato.

È possibile aggiornare le versioni dei dati al primo tentativo di accesso o farlo al momento dell'aggiornamento del software.

Ma sarebbe meglio non farlo regolarmente (nei report ad esempio). Se manterrai intatte le vecchie versioni dei tuoi dati, molto presto avrai una versione da incubo. Dovrai supportare le vecchie versioni ovunque nella tua app.

    
risposta data 29.05.2016 - 18:32
fonte
0

Quando aggiungi una nuova colonna a una tabella di un database, di solito dai alla colonna un valore predefinito o aggiorni le righe correnti nello stesso script. Stai facendo la stessa cosa qui, solo con l'aggiunta di una stringa serializzata invece di un tavolo, è un po 'più complicato.

Molte implementazioni SQL hanno strumenti per analisi e writing XML, in modo da poter scrivere uno script per eseguire la scansione del database e aggiornare tutti i record contemporaneamente.

L'inconveniente qui è che ci vorrà del tempo. Se ci sono troppe righe per aggiornarle tutte in una volta, puoi fare ciò che Caleth suggerito e aggiornato sull'accesso. Quindi, dopo aver aggiornato un numero sufficiente di record, esegui lo script per ottenere gli ultimi.

Se possibile, refactoring del database per avere una tabella separata per gli articoli o una colonna XML invece di utilizzare le stringhe XML potrebbe rendere gli aggiornamenti futuri più facili e veloci. Se non vuoi seguire questa strada, aggiungere un numero di versione al tuo XML renderà molto più facile dire cosa dovrebbe essere nell'oggetto deserializzato. Non vuoi più di una dozzina di if (property == null) { createProperty(); } di righe nel tuo deserializzatore.

    
risposta data 28.06.2016 - 21:22
fonte

Leggi altre domande sui tag