Domanda

Ho esaminato alcuni hook di controllo con Entity Framework.Molti di essi mostrano confronti tra valori vecchi e nuovi.Questo è ottimo per una traccia di controllo, ma sto cercando di eseguire lo snapshot degli oggetti.

Per esempio...Diciamo che ho un'applicazione che gestisce i prodotti.Un prodotto ha più attributi e altri oggetti associati.Diciamo che cambio un oggetto 10 volte.Diciamo anche che è importante poter visualizzare le schermate delle modifiche agli oggetti (non una traccia di controllo ma l'aspetto effettivo della schermata in un formato di sola lettura).Ciò che mi interessa è poter recuperare l'oggetto prodotto EF originale (con tutti i dati associati) per tutte e 10 le modifiche (a seconda di quale voglio vedere) e utilizzarlo per associarlo al mio schermo.

Se utilizzo SQL Server, quale tipo dovrei utilizzare oggigiorno per l'oggetto serializzato (XML, blob, ecc.)?Ha senso farlo?

È stato utile?

Soluzione

Vediamo. Hai l'obbligo di tenere un oggetto grafico e serializzare nel database in un formato che vi permetterà di materializzare in un secondo momento. Penso che ci sono strumenti che fanno esattamente questo. Uno di loro, mi colpisce, è l'Entity Framework.

Che cosa si vuole fare è una cosa molto comune. Si consideri un motore wiki. Il wiki ha bisogno di avere una revisione di punta che tutti vedono, oltre a revisioni posteriori di ogni documento. Il wiki deve anche essere in grado di visualizzare una revisione indietro nel proprio stesso modo in cui viene visualizzata una revisione di punta. Pertanto, lo stesso formato di memorizzazione deve essere usato per entrambi.

Io proporrei che si consenta tutti i tipi di entità da versione. Quando si modifica un tipo di entità, si modificare il revisione di punta e memorizzare una revisione posteriore contenente i valori precedenti. (Il motivo per cui si modifica la revisione punta invece di inserire una nuova punta è perché altri oggetti, che non sono attualmente materializzati in un ObjectContext, possono contenere link a punta che si desidera conservare come link alla punta, piuttosto che collegamenti a la revisione di nuovo).

Se necessario, è possibile partizionare le tabelle di SQL Server in modo che le revisioni posteriori sono memorizzati in un gruppo di file diverso. Ciò consentirebbe di eseguire il backup le revisioni di punta e le revisioni retro separatamente.

Altri suggerimenti

Per prima cosa è necessario aggiungere una serie di immobili da tabelle:

  • Versione -. Il tempo di ultima modifica (può anche essere autoincrementing contatore invece di tempo)
  • LastModifiedBy -. Di riferimento per l'utente che ha reso ultima modifica (se si memorizzano che)

Poi sono disponibili diverse opzioni su come memorizzare la cronologia delle versioni. Puoi

  1. Creare una nuova tabella per ciascuno dei principali tabelle che si desidera memorizzare la storia per. Che le tabelle di storia avranno tutti gli stessi campi come tabella principale, ma le chiavi primarie ed esterne non verranno applicate. Per ogni chiave esterna anche memorizzare la versione di entrata si fa riferimento alla versione tempo è stato creato.

  2. In alternativa è possibile serializzare tutto interessante circa il vostro soggetto e memorizzare tutti che macchie serializzati per tutte le entità che si desidera la versione in una tabella della cronologia globale (io personalmente preferisco primo approccio).

Come si fa a riempire le tabelle di storia? Via aggiornamento ed eliminare i trigger.

  • In aggiornamento di trigger per il vostro entità - copiare tutti i valori precedenti alla tabella di storia. Per ogni chiave esterna - anche copiare attuale Versione di entità di riferimento
  • .
  • In trigger di eliminazione - fondamentalmente fare la stessa
  • .

Si noti che i sistemi sempre più moderne realtà non cancellare nulla. Hanno appena marchio le cose come cancellato. Se si vuole seguire questo modello (che ha diversi vantaggi) -. Invece di eliminare aggiungere bandiera IsDeleted ai tuoi entità (ovviamente è quindi necessario filtrare entità eliminate ovunque out)

Come vedi la vostra storia? Basta usare tabella di storia, dal momento che ha tutte le stesse proprietà di tabella principale - non dovrebbe essere un problema. Ma - in caso di ampliamento chiavi esterne - garantire che entità di riferimento versione è lo stesso che si memorizzano nella tabella storia. Se non è - è necessario andare al tavolo di Storia che i valori di entità e afferrare riferimento lì. In questo modo si avrà sempre una fotografia di come entità sembrava in quel momento, tra cui tutti i riferimenti.

In aggiunta a tutto sopra - è anche possibile ripristinare lo stato del soggetto a qualsiasi versione precedente.

Si noti che questa implementazione, mentre semplice, può consumare un po 'di spazio, perché memorizza snapshot , non solo cambiamenti in atto. Se si desidera memorizzare solo variazioni - in aggiornamento grilletto è possibile rilevare quali campi è stato modificato, loro e conservare serializzare nella tabella di storia globale. In questo modo si può almeno mostra a un'interfaccia utente che cosa è stato modificato e da chi (anche se si potrebbe avere problemi al ritorno ad una qualche versione precedente).

In un progetto che ho creato di recente abbiamo utilizzato il collegamento a SaveChanges metodo nel DbContext classe.Questo ci ha dato accesso a un'istanza di ChangeTracker classe.Chiamando ChangeTracker.Entries() ti dà accesso a un elenco di DbEntityEntry. DbEntityEntry ha le seguenti proprietà e metodi interessanti:

  • State - è l'oggetto appena creato, modificato o in fase di eliminazione
  • Entity - una copia dell'oggetto così com'è
  • CurrentValues - un'enumerazione dei valori modificati
  • OriginalValues - un'enumerazione dei valori originali

Abbiamo creato un set di POCO per set di modifiche e modifiche a cui potremmo quindi accedere tramite EF.Ciò ha consentito ai nostri utenti di visualizzare le modifiche a livello di campo insieme alle date e agli utenti responsabili.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top