Domanda

Ho un processo che è l'importazione di Excel Spreadhseet, e l'analisi dei dati nella mia oggetti dati.La fonte di questi dati è molto discutibile, come ci stiamo muovendo i nostri clienti da un foglio di calcolo di base di gestione dei dati in un database gestito con sistema di controlli di dati validi.

Durante il mio processo di importazione, faccio un po ' di base di controlli di integrità dei dati per accogliere quanto male la data potrebbe essere che stiamo importando, ma ho i miei validazione complessiva, fatta in DbContext.

Parte di quello che sto cercando di fare è che ho intenzione di fornire la Riga # nel foglio di calcolo che i dati è male in modo da poter facilmente determinare ciò che è necessario risolvere per ottenere il file da importare.

Una volta che ho i dati dal foglio di calcolo (model), e l'Opportunità che stiamo lavorando con il database (oppqui lo pseudocodice del mio processo:

foreach (var model in Spreadsheet.Rows) { // Again, pseudocode
    if(opp != null && ValidateModel(model, opp, row)) {
        // Copy properties to the database object

        // This is in a Repository-layer method, not directly in my import process.
        // Just written here for clarity instead of several nested method calls.
        context.SaveChanges(); 
    }
}

Posso fornire il codice qui, se necessario, ma il problema viene nel mio DbContext s ValidateEntity() metodo (override di DbContext).

Di nuovo, non c'è niente di sbagliato con il codice che mi hai scritto, per quanto ne sono a conoscenza, ma se un'Opportunità che non è riuscito questo livello di validazione, poi rimane come parte dei non salvati oggetti in context, il che significa che più volte tenta di convalidare ogni volta che il ValidateEntity() viene chiamato.Questo porta a una ripetizione dello stesso messaggio di Errore di Convalida per ogni riga, dopo l'iniziale problema si verifica.

C'è un modo per [modifica]ottenere il Contesto di smettere di cercare di convalidare l'oggetto dopo che convalida una volta[modifica]?So che potrei aspettare fino alla fine e chiamata context.SaveChanges() una volta, al fine di ottenere intorno a questo, ma vorrei essere in grado di abbinare questo con quello che riga è nel Database.

Per riferimento, io sono l'utilizzo di Entity Framework 6.1 con un Codice di Primo approccio.

MODIFICA Nel tentativo di chiarire ulteriormente per Marc L.(tra cui un aggiornamento per il blocco di codice sopra)

Ora, il mio processo di scorrere tutte le righe che ci sono nel Foglio di calcolo.Il motivo per cui sto chiamando il mio Repository strato con ogni oggetto, per risparmiare, invece di lavorare con un approccio che solo chiamate context.SaveChanges() una volta è quello di permettere a me stesso la possibilità di determinare a quale riga è quello che causa un errore di convalida.

Sono contento che la mia DbContext personalizzato ValidateEntity() metodi di cattura gli errori di validazione, ma il problema risiede nel fatto che si tratta di non buttare il DbEntityValidationException per la stessa entità più volte.

Vorrei farlo in modo che, se l'oggetto di convalida una volta, il contesto non è più tenta di salvare l'oggetto, indipendentemente dal numero di volte context.SaveChanges() viene chiamato.

È stato utile?

Soluzione

La tua domanda non è una vittima, una vittima (questo è il risparmio, non caricato entità), ma si potrebbe seguire Jimmy consigli di cui sopra.Che è, una volta che un'entità, è aggiunto il contesto è traccia nel "aggiunto" e l'unico modo per fermare la ri-convalida è scollegandolo.E ' un MODO-collegamento interno, ma io a riprodurre il frammento di codice:

dbContext.Entry(entity).State = EntityState.Detached;

Tuttavia, non credo che il modo in cui si vuole andare, perché si sta utilizzando eccezioni per gestire lo stato inutilmente (le eccezioni sono notoriamente costosi).

Di lavoro dalle informazioni date, mi piacerebbe utilizzare un altro set-soluzione a base di:

  • modificare il modello di classe in modo che contenga un RowID che registra l'originale del foglio di calcolo di fila (probabilmente ci sono altri buoni motivi per avere questo, troppo)
  • disattivare il monitoraggio delle entità per il contesto (si gira di rilevamento delle modifiche, consentendo a ciascun Add() O(1))
  • aggiungere tutti gli enti
  • chiamata context.GetValidationErrors() e ottenere tutti i tuoi errori in una sola volta, utilizzando il suddetto RowID per identificare le voci righe.

Non indicare se il processo deve salvare il buon righe o rifiutare il file come un intero, ma questo sarà in grado di ospitare sia-che è, se è necessario salvare il buon righe, scollegare tutte le voci di righe utilizzando il codice qui sopra e poi SaveChanges().


Infine, se si desidera salvare il buon righe e sei a disagio con il set di base di metodo, sarebbe meglio utilizzare un nuovo DbContext per ogni singola riga, o almeno creare un nuovo DbContext dopo ogni errore.Il ADO.NET team insiste sul fatto che il contesto-la creazione è "relativamente basso" (mi dispiace non avere un citare la o le statistiche a portata di mano per questo) quindi questo non dovrebbe danneggiare il throughput di troppo.Anche così, per lo meno rimanere O(n).Non vorrei darti torto, la gestione di un ampio contesto può aprire fino ad altri problemi.

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