2010-09-16 1 views
6

Sto cercando di aggiornare i dati mentre li sto leggendo dal database, vedi sotto. Ma dopo che tutto è finito, i dati non sono stati aggiornati.Perché non posso aggiornare i dati nel database usando LINQ to SQL?

C'è qualche sintassi di transazione che devo specificare? (Quando il debug, posso vedere io ho il record di destra recuperate.)

using (conn = new SqlConnection(MyConnectionString)) 
       using (SqlCommand cmd = new SqlCommand("dbo.MyProcedure", conn)) 
       { 
        cmd.CommandType = CommandType.StoredProcedure; 
        cmd.Parameters.AddWithValue("@Count", count); 
        conn.Open(); 
        using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) 
        { 
         while (reader.Read()) 
         { 
          // wrapper object, not related to database 
          SampleModel c = new SampleModel(); 
          c.ID= (string)reader["ID"]; 
          c.Name = (string)reader["Name"]; 
          c.Type = (int)reader["Type"]; 

          // modeList will return to outside, not related to database 
          modelList.Add(c); 

          sampleTable1 table1 = context.sampleTable1s.SingleOrDefault(t=> t.id = c.ID); 

          // try to update the "isRead", but it doesn`t work....!!! 
          // about the datatype, in the data base, it is "smallInt" 
          // in linq to sql, it is "short?" 
          // PS Default value all should be 0 
          table1.isRead = 1; 
          context.SubmitChanges(); <--- here, it doesn`t do the job // context is new from Linq to SQL 
         } 
        } 
        conn.Close(); 
       } 

Ecco la mia procedura:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE PROCEDURE MyProcedure  
    @Count int = 100 
AS 
BEGIN 

    SELECT TOP (@Count) 
     t1.id AS ID, 
     t1.name AS Name, 
     t2.type AS TYPE  
    FROM sampleTable1 as t1 with (nolock), 
     sampleTable2 as t2 with (nolock)   
    WHERE (t1.t2Id = t2.Id)  
ORDER BY t1.name asc 

END 
GO 

E se ho messo tutto il mio codice all'interno di TransactionScope blocco

using (TransactionScope scope = new TransactionScope()) 
{ 
    // all the C# code above 
    scope.Complete(); 
} 

Otterrò un'eccezione "MSDTC sul server 'localhost-sqlserver2005' non è disponibile."

E se solo ho messo una parte del codice, non esiste alcuna eccezione, ma i dati vengono aggiornati did`t

using (TransactionScope scope = new TransactionScope()) 
{ 
    sampleTable1 table1 = context.sampleTable1s.SingleOrDefault(t=> t.id = c.ID); 

    table1.isRead = 1; 
    context.SubmitChanges(); 

    scope.Complete(); 
} 

Grazie.

+0

noloack? chiedendo se quello è un errore nella domanda o un SPROC rotto –

+0

Per confermare - cosa è 'table1.isRead' * prima * questo? Applica solo * cambiamenti * effettivi, quindi se era 1 prima, nessun cambiamento. Hai provato a catturare il log ('context.Log = Console.Out;') per vedere cosa sta inviando? (Alternativa simile: utilizzare un profiler SQL) –

+0

@Marc, è un errore di battitura ... – jojo

risposta

8

Verificare che almeno un membro nella classe di entità in questione sia contrassegnato come membro di chiave primaria nella finestra di progettazione di L2S. Se un'entità non ha alcun membro PK, L2S lo ignorerà silenziosamente durante l'invio degli aggiornamenti (silenziosamente come non viene generata alcuna eccezione e nessuna istruzione SQL di aggiornamento generata e inviata a db).

+1

.. sei genio ... ho dimenticato di creare la chiave primaria nel mio script. fammi provare cosa è successo dopo che ho messo un primario su – jojo

+1

che sta funzionando ora .....-_- !!!! – jojo

+0

Solo una nota aggiuntiva: la chiave per ottenere le istruzioni di aggiornamento (ed eliminazione) è se il modello pensa che ci sia un PK. La cosa migliore è ovviamente se c'è un PK nel DB, ma per le situazioni in cui la tabella DB non ha un PK è sufficiente marcare una o più colonne (che identificano univocamente i record) come membri PK e L2S sarà felice . – KristoferA

2

Assicurarsi di disporre della chiave primaria impostata per tale tabella. Se non puoi farlo nel db, fallo nel designer linq2sql.

Ha risposto a questo here, here e here. Lo menzionò anche linq to sql pitfalls.