2012-06-29 11 views
5

Poiché EF non supporta i contorni delle chiavi univoci, sembra che sia necessario rilevare un'eccezione durante il metodo di salvataggio e visualizzare un messaggio di errore all'utente.Codice EFPrima di gestire le eccezioni del database durante il salvataggio delle modifiche

I problemi con questo approccio sono:

  • Come facciamo a sapere che registrano ha generato un'eccezione
  • Come facciamo a sapere che tipo di problema ha generato un'eccezione (ex potrei avere due vincoli unici su stesso disco, quindi ho bisogno di dire all'utente quale è rotto)

DBMS è SqlServer 2008.

Come risolvere questi problemi?

risposta

2

Se si consente che un utente può inserire i valori che devono essere univoco nel database è necessario convalidare questo ingresso prima di salvare le modifiche:

if (context.Customers.Any(c => c.SomeUniqueProperty == userInput)) 
    // return to user with a message to change the input value 
else 
    context.SaveChanges(); 

questo non è solo il caso di valori con vincoli univoci nel database ma anche per l'immissione di valori di chiavi esterne che devono fare riferimento a record di destinazione esistenti o valori di chiave primaria se la chiave primaria non viene generata automaticamente nel database. EF non ti aiuta in quest'ultima situazione perché un contesto non conosce il contenuto dell'intera tabella del database ma solo le entità attualmente associate al contesto. È vero che EF proibirà di collegare due oggetti con la stessa chiave primaria, ma consente a due oggetti con lo stesso vincolo di chiave univoco. Ma questo non ti protegge completamente dalle violazioni dei vincoli delle chiavi primarie quando salvi le modifiche al database.

Nel caso improbabile che tra il controllo Any e SaveChanges un altro utente ha inserito un record con lo stesso valore, vorrei prendere in considerazione l'eccezione si verificano, come non è possibile gestire e basta dire che l'utente "Si è verificato un errore previsto, riprova ancora...". Se l'utente prova di nuovo, il controllo Any si ripete e otterrà il messaggio più utile per modificare il valore di input dal codice sopra riportato.

L'eccezione restituita per tale limitazione di chiave univoca o violazione di vincolo di chiave primaria è un generale DbUpdateException e una delle eccezioni interne sarà un SqlException che contiene come una delle sue proprietà un codice di errore di SQL Server. Qualsiasi altro dettaglio può essere trovato solo nel messaggio di eccezione "Violazione del vincolo UNIQUE KEY IX_SomeUniqueProperty_Index ..." o simile. Se si prevede che l'utente possa capire e reagire di conseguenza a queste informazioni, è possibile visualizzarlo. Altrimenti puoi registrare questo messaggio per un amministratore o uno sviluppatore per verificare possibili bug o altri problemi.

+0

Quindi, dal momento che sto eseguendo aggiornamenti in batch, questo richiederebbe di trovare record aggiornati/aggiunti in Clienti e di scorrere in loop ogni record per verificare se esiste un record esistente con lo stesso valore. Non sono abbastanza sicuro di come influirà sulle prestazioni quando ci sono più di 10 record che sono stati modificati. O in questo caso è meglio prendere un'eccezione? Il messaggio deve essere localizzato, quindi sembra che ho bisogno di creare una procedura che faccia una ricerca di messaggi per IX_SomeUniqueProperty, poiché il messaggio può essere anche in francese, se il sistema operativo è francese (se non sbaglio), e non posso dipendere in "Violazione di ...." – Goran

+0

@Goran: Vedo, ma vorrei comunque eseguire una query per verificare l'esistenza. Se è necessario anche * aggiornare * come si dice, non solo inserire, non è necessario interrogare l'entità nel database comunque? Non è possibile decidere tra l'aggiornamento e l'inserimento senza sapere se l'entità è già presente nel DB o meno. – Slauma

+0

La decisione tra l'aggiornamento e l'inserimento è presa da EF stesso.Qualsiasi entità che ho aggiunto alla raccolta Clienti è considerata come nuovo record, i record con PK già assegnato verranno aggiornati. Quello che devo coprire è il caso in cui un utente della rete ha aggiunto un record (i dati del cliente nella maggior parte dei casi non sono aggiornati con i dati del database, poiché ciò richiederebbe una risincronizzazione costante), quindi potrebbero essere trascorsi 15 minuti tra l'ultimo carica dati e salva le chiamate. Per questo motivo non posso solo dipendere dai dati memorizzati nella cache del client per verificare se esistono vincoli univoci (o qualsiasi altro). – Goran

Problemi correlati