2012-07-02 20 views
7

Uso di asp.net 4 anche se C#.LINQ to SQL - aggiornamento record

Nel mio livello di accesso ai dati ho metodi per salvare e aggiornare i record. Il salvataggio è abbastanza facile ma l'aggiornamento è noioso.

Ho usato in precedenza SubSonic che era eccezionale perché aveva un record attivo e sapevo che se avessi caricato un record, modificato alcune voci e poi salvato di nuovo, lo riconobbe come un aggiornamento e non provò a salvare un nuovo entrata nel DB.

Non so come fare la stessa cosa in LINQ. Di conseguenza il mio flusso di lavoro è simile a questo:

  1. pagina Web palio 'Record A' dal DB
  2. Alcuni valori in esso vengono modificate dall'utente.
  3. 'Record A' viene passato al livello di accesso ai dati
  4. Ora ho bisogno di caricare nuovamente Record A, chiamandolo 'SavedRecord A', aggiornare tutti i valori in questo oggetto con i valori del 'Record A' passato e quindi aggiorna/salva "SavedRecord A"!

Se si salva solo "Record A", arrivo con una nuova voce nel DB.

Ovviamente sarebbe bello passare Basta registrare e fare qualcosa di simile:

RecordA.Update(); 

sto presumendo che c'è qualcosa che mi manca qui, ma non riesco a trovare una risposta diretta on-line.

risposta

1

Quando LINQ-to-SQL aggiorna un record nel database, ha bisogno di sapere esattamente quali campi sono stati modificati per aggiornarli. Hai sostanzialmente tre opzioni:

  • Quando i dati aggiornati viene inviato al server web, caricare i dati esistenti dal database, assegnare tutte le proprietà per l'oggetto caricato e chiamare SubmitChanges(). Qualsiasi proprietà a cui è stato assegnato il valore esistente non verrà aggiornata.
  • Tieni traccia dello stato non modificato dell'oggetto e usa Attach con entrambi i valori non modificati e modificati.
  • Inizializza un nuovo oggetto con tutto lo stato richiesto dal controllo di concorrenza ottimistico (se attivato, che è per impostazione predefinita).Quindi allegare l'oggetto e aggiornare infine eventuali proprietà modificate dopo il il collegamento per rendere il tracker di modifiche DataContext essere a conoscenza di quelli aggiornati.

Di solito uso la prima opzione in quanto è più semplice. C'è una penalità di prestazioni con due chiamate DB, ma a meno che non si stiano facendo molti aggiornamenti, non importa.

+0

Grazie, è un po 'sorprendente che non ci sia un modo migliore per farlo. Ho fatto il metodo 'due chiamate DB' da quando ho iniziato a usare LINQ to SQL ma ho sempre avuto la sensazione fastidiosa che mi mancasse una risposta ovviamente più semplice. Sembra che io non abbia, il che è sia buono sia cattivo. –

2

si può realizzare quello che vuoi utilizzando il Attach method nell'istanza Table, e commettendo tramite il metodo SubmitChanges() sul DataContext.

Questo processo potrebbe non essere semplice come vorremmo, ma è possibile leggere LINQ to SQL: Updating Entities di David DeWinter per una spiegazione/tutorial più approfondita.

+0

THanks, lo verificherò. –

1

diciamo che avete una classe di prodotto OR DB, quindi dovrete farlo.

DbContext _db = new DbContext(); 

    var _product = (from p in _db.Products 
            where p.Id == 1 // suppose you getting the first product 
            select p).First(); // this will fetch the first record. 

    _product.ProductName = "New Product"; 

    _db.SaveChanges(); 

     // this is for EF LINQ to Objects 
    _db.Entry(_product).State = EntityState.Modified; 
    _db.SaveChanges(); 

------------------------------------------------------------------------------------- 
this is another example using Attach 
------------------------------------------------------------------------------------- 

public static void Update(IEnumerable<Sample> samples , DataClassesDataContext db) 
{ 
    db.Samples.AttachAll(samples); 
    db.Refresh(RefreshMode.KeepCurrentValues, samples) 
    db.SubmitChanges(); 
} 

se si collega l'entità al contesto e quindi aggiornare (con KeepCurrentValues ​​selezionati), LINQ to SQL otterrà quelle entità dal server, confrontarli, e segnare aggiornato coloro che sono diversi

+0

Grazie, nel mio caso però non saprò davvero quali campi sono stati modificati mentre l'utente eseguirà il montaggio. Quindi devo supporre che tutti i campi siano cambiati e scrivere di conseguenza l'aggiornamento. È noioso, ma almeno ora so che lo sto facendo nel modo "giusto", anche se non sembra. –

+0

non importa quali campi sono stati modificati dall'utente, se si passa il modello all'azioneRisultato nel controller nel metodo HTTPPOST e si chiama SaveChanges(), l'intero record viene aggiornato nel DB. –

+0

Quindi, è possibile eseguire questo lavoro in cui il client ha restituito solo un singolo valore modificato + un campo di riferimento chiave? Diciamo che si passa loro un record serializzato e si passa indietro un record serializzato aggiornato contenente solo i due campi. Finora nei miei test, LinqToSql ha appena provato a sovrascrivere i dati esistenti con valori null. Ovviamente questo significa che non si sarà mai in grado di annullare esplicitamente un campo Null. Cercando di evitare di scrivere un sacco di questo campo = quel campo. – RoboJ1M