2012-01-13 16 views
16
Error Message: Row not found or changed. 
Stack Trace: 
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode) 
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) 

Ciò si verifica in modo apparentemente casuale. Ho ricevuto e-mail questi errori e l'URL segnalato sembra funzionare sempre per me e dovrebbe funzionare anche per tutti gli altri.Riga Linq non trovata o modificata

posso risolvere questo errore:

  • Andando alla mia dbml disposizione
  • Selezionando ogni campo nella tabella che causano conflitti
  • clic destro e impostare la proprietà Update Check a Never

Questo sembra evitare che questi tipi di errori vengano lanciati.

Tuttavia, è faticoso ricordarsi di continuare a fare ogni volta che riesco a fare il dmbl, aggiungere nuove tabelle, ecc. Esiste un modo migliore per risolvere questo problema? Sto ricevendo forse 50-100 di questi al giorno, il che è un male per i miei visitatori.

+0

mi piacerebbe verificare che i tipi di dati ei vincoli nulli corrispondono esattamente tra il dbml e il database. – codingbadger

+0

@Barry si lo fanno tutti, ho aggiunto di nuovo ogni tabella –

risposta

27

Ogni volta che ho visto questo errore, significa che qualcosa è cambiato nel database tra il momento in cui ho caricato il record/oggetto/qualsiasi cosa e quando stavo cercando di salvarlo. Senza dubbio, è stato perché la mia unità di lavoro era troppo grande.

Non conosco la natura esatta della vostra applicazione, ma presumo che si stia creando un contesto dati, caricando un record o un elenco di record, eseguendo alcune operazioni su di esso, masticando un po 'di tempo e cicli del processore, e poi alla fine cercando di salvare i dati modificati nel database. Forse anche caricando un'istanza di un record/oggetto e memorizzandola in una variabile di classe per un po ', e poi alla fine di un caricamento o thread di una pagina o qualsiasi altra cosa provando a salvare di nuovo tutto ciò che è cambiato. Il problema è che poiché LINQ ne ha memorizzato una copia, quella è la copia che vuole aggiornare. Se i dati sottostanti cambiano nel frattempo, si arrabbia.

Chiedetevi questo, e se metteste una transazione di blocco sui vostri dati per l'intera vita dei vostri oggetti. Qualsiasi cosa tu abbia caricato, qualcuno potrebbe modificare, a nessun altro sarebbe permesso di toccarlo durante quel periodo. Fondamentalmente questo è l'assunto qui. Certo, LINQ è un po 'più ottimista a riguardo, non ha senso bloccare la riga o il tavolo se non si stanno aggiornando i dati, ma si pensa a questi problemi. Chiediti cosa potrebbe rompersi o rallentare in modo significativo se si inserissero serrature transazionali rigorose sugli oggetti e questo probabilmente ti indirizzerà al codice incriminato.

La mia soluzione a questo è di mantenere la mia unità di lavoro il più piccola possibile. Non caricare l'oggetto e utilizzarlo come copia di lavoro e memorizzarlo nel database, tutto in un unico contesto. Invece, carica l'oggetto ed estrai le informazioni che ti servono in un solo passaggio, quindi scopri le modifiche che devi applicare, quindi carica/aggiorna/salva l'oggetto. Certo, provoca più round trip nel database, ma ti dà una migliore garanzia che stai lavorando con l'ultima copia di dati. Sarà ancora "last in, wins", il che significa che se qualcuno ha fatto un aggiornamento mentre lavoravi con i dati potrebbe essere perso, ma questo è sempre un rischio a meno che non blocchi il record con una transazione. Tuttavia, ti offre la flessibilità che se qualcun altro sta modificando campi non correlati nella stessa riga, entrambi possono operare insieme su questi dati.

+0

Grazie, questa è una buona risposta. Comunque è stato gettato su alcune pagine che considero leggere, il nostro server non è molto potente e prevediamo di effettuare l'aggiornamento a breve. Se il server è un po 'lento, potrebbe lanciare questo errore ogni tanto quando diventa occupato? Elaboriamo un buon numero di pagine viste mensili –

+0

Sì, leggero e lento sono tutte una scala mobile variabile. Se il server rallenta, le pagine sono di peso relativamente più pesante. Se il sito si rallenta, c'è più possibilità che i thread entrino in conflitto l'uno con l'altro –

+0

Un'altra cosa da notare è che anche le colonne devono corrispondere. Ho avuto questo problema, e ho fatto qualcosa di stupido. Stavo usando un proc memorizzato per ottenere i miei dati, dato che la query era molto complessa, e quindi stavo usando Linq per cancellare quegli stessi record. Il problema che ho avuto è che ad un certo punto avevo aggiunto alcune nuove colonne a quella tabella, ma il mio codice non le stava impostando nel modello in quanto non erano necessarie in quel momento. Ciò mi ha causato l'errore sopra menzionato quando provavo a usare Linq per cancellare i record. –

2

GetTable(). Attach (newEntity, originalEntity);

Se non si sta utilizzando un campo versione da aggiornare, il metodo precedente parametrizza i nuovi dettagli e le entità dei dettagli precedenti, se l'entità originale viene modificata a questo punto si otterrà comunque lo stesso errore, questo dipende da voi per garantire. Funziona come un fascino, l'ho provato.

49

Ho avuto lo stesso problema e l'ho risolto confrontando dbml con la struttura db. Una proprietà non è stata impostata su Null e ciò ha causato il problema.

Controllare quindi le proprietà dbml e nullable.

+0

Questo è stato il mio caso, grazie. – GerManson

+0

Questo è stato esattamente per me, grazie. – mariocatch

+0

+1, l'aggiornamento del contesto ha risolto il problema - grazie per il suggerimento – agrath

1

A volte è davvero semplice ... Assicurarsi che non ci siano serrature sul tavolo. Nel mio caso, l'interfaccia utente di SQL Server Management Studio conteneva blocchi di cui non ero a conoscenza (non ricordo) mentre stavo eseguendo il debug. Lo scarico ha cancellato quelle serrature e le cose hanno iniziato a funzionare di nuovo.

0

Stavo ricevendo questo errore su Windows Phone 8. E mi ci è voluto un po 'per capire quale fosse il problema. Fondamentalmente era questo:

Avevo una classe chiamata TrackingInformation. 1. Da un server ho recuperato una versione aggiornata di esso. 2. My TileService ha aggiornato il riquadro secondario con le sue informazioni e (!!) ha aggiornato 1 proprietà e lo ha salvato nel database locale sul telefono. 3. Ho provato a salvare nuovamente la prima istanza dell'oggetto e qui ho ricevuto l'errore "riga non trovata o modificata".

Per me ho dovuto rimuovere la terza parte e ha funzionato correttamente (ero già stato salvato con la versione aggiornata). Ma dal momento che una proprietà lo aveva cambiato ha gettato un'eccezione ...

Non vedo l'ora che EF7 arrivi a Windows Phone, così tanto mal di testa con l'attuale EF su WP8.

1

Utilizzo di SQL Profiler ho rintracciato le transazioni SQL verso il mio server e si rese conto che sul SubmitChanges() l'trasmessa UPDATE dichiarazione contiene un valore errato nella clausola WHERE. Questo è perché ho una proprietà che assomiglia a questo:

class Position{ 
... 
    [Column] 
    public int Pieces{ 
     get{ 
      this.pieces = this.Transformers.Count; 

      return this.pieces; 
     } 
     set{ this.pieces = value; } 
    } 
... 
} 

Dal Transformers è un elemento List<Transformers> che rappresenta un elenco di uno-a-molti rapporti con un'altra Transformers tavolo, devo manualmente per riempire il List con ogni Transformer che contiene una chiave esterna per l'oggetto Position. Se, per qualche ragione, non lo faccio, ricevo l'errore menzionato perché la proprietà Pieces è influenzata dal valore originale.

Così, l'istruzione SQL su SubmitChanges() cercherà una voce WHERE Pieces = somevalue ma il valore effettivo del Pieces nella voce è anothervalue. Quindi basicamente LINQ penserà che tu abbia cambiato qualcosa nel db nel frattempo, perché il db non restituirà alcun valore a questa richiesta.

Come detto, una soluzione è:

[Column(UpdateCheck=UpdateCheck.Never)] 
    public int Pieces 
    { 
     get { 
      this.pieces= this.Transformers.Count; 

      return this.pieces; 
     } 
     set { this.pieces= value; } 
    } 

Naturalmente questo può anche essere facilmente risolto impostando una semplice funzione getter come

getPieces(){ 
    return this.Transformers.Count(); 
} 

e una proprietà di "imparziale"

class Position{ 
... 
    [Column] 
    public int Pieces{ 
     get{ return this.pieces; } 
     set{ this.pieces = value; } 
    } 
... 
} 

Spero che questo possa essere di aiuto a qualcuno. Inserisco questo anche perché se qualcun altro avesse prima, mi avrebbe risparmiato ore della mia vita.

2

Ciò può verificarsi anche se un trigger del database modifica qualsiasi colonna di una riga che si sta aggiornando, anche se non si sta aggiornando quella particolare colonna.

Dovrete ricontrollare che nessuna delle tabelle interessate nella vostra unità di lavoro non ha trigger su di esse. Se utilizzi i trigger di aggiornamento, probabilmente vorrai assicurarti che le colonne aggiornate siano NeverCheck.

0

aggiornamento LINQ to SQL in schema problema progettista risolvere nel mio caso

+0

Anche se questo potrebbe essere un suggerimento prezioso per risolvere il problema, una buona risposta dimostra anche la soluzione. Si prega di [modificare] per fornire un codice di esempio per mostrare cosa intendi. In alternativa, considera di scrivere questo come un commento. –