2010-09-16 13 views
6

Estoy tratando de actualizar los datos mientras los estoy leyendo desde la base de datos, ver a continuación. Pero después de que todo terminó, los datos no se actualizaron.¿Por qué no puedo actualizar los datos en la base de datos usando LINQ to SQL?

¿Hay alguna sintaxis de transacción que deba especificar? (Cuando elimino errores, puedo ver que tengo el registro correcto recuperada.)

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(); 
       } 

Aquí es mi procedimiento:

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 

Y si pongo todo mi código dentro TransactionScope bloque

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

Recibiré una excepción "MSDTC en el servidor 'localhost-sqlserver2005' no está disponible."

Y si sólo pongo una parte del código, no constituye una excepción, pero los datos se actualizan did`t

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

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

    scope.Complete(); 
} 

Gracias.

+0

noloack? preguntándose si eso es un error tipográfico en la pregunta, o un SPROC roto –

+0

Para confirmar, ¿qué es 'table1.isRead' * antes de * esto? Solo aplica cambios * reales, por lo que si fue 1 antes, no hay cambio. ¿Has intentado capturar el registro ('context.Log = Console.Out;') para ver lo que está enviando? (alternativa similar - use un generador de perfiles SQL) –

+0

@Marc, es un error de tipeo – jojo

Respuesta

8

Compruebe que al menos un miembro de la clase de entidad en cuestión está marcado como miembro de clave principal en el diseñador de L2S. Si una entidad no tiene ningún miembro de PK, L2S lo ignorará silenciosamente cuando envíe actualizaciones (silenciosamente como en ninguna excepción lanzada, y no se generará ninguna declaración SQL de actualización y se enviará a db).

+1

.. sois genios ... me olvido de crear la clave principal en mi script. déjame probar lo que sucedió después de poner un primario en – jojo

+1

, está funcionando ahora .....-_- !!!! – jojo

+0

Solo una nota adicional: la clave para obtener las declaraciones de actualización (y eliminar) es si el modelo piensa que hay una PK. Lo mejor es, por supuesto, si hay un PK en el DB, pero para situaciones donde la tabla de DB no tiene un PK es suficiente marcar una o varias columnas (que identifican registros de manera única) como miembros de PK y L2S será feliz . – KristoferA

2

Asegúrese de tener la clave primaria establecida para esa tabla. Si no puede hacer eso en el db, hágalo en el diseñador linq2sql.

Respondido here, here y here. También lo mencioné linq to sql pitfalls.

Cuestiones relacionadas