2010-05-17 6 views
6

Esto es extraño ... ha hecho actualizaciones muchas veces pero no ve por qué es diferente. aunque estoy usando .net 4.0 ahora, sin embargo, dudo que sea un error en su implementación de L2S. No es así, es una aplicación extraña y maravillosa. Aunque estoy bastante seguro de que este código funcionó mientras estaba usando el RC.Linq2Sql - intentando actualizar, pero la instrucción Set en sql está vacía

También he logrado reproducir este error construyendo un proyecto desde cero utilizando la información a continuación.

el problema aquí es que la declaración de actualización generada por L2S no tiene campos en la instrucción set. He intentado comprobar que el pk está configurado (solo por qué creo que se requeriría un campo ervery en el where) y también leí las otras propiedades de dbml. He estado usando linq2Sql durante aproximadamente 1 año y nunca he tenido un problema. Todavía creo que estoy teniendo un gran pedo cerebral.

Nota: he limpiado los métodos iguales y GetHashCode para eliminar algunos campos; el problema persiste después de esto. Aunque no he limpiado el SQL.

que tienen una clase de cliente desde el dbml añadí un método denominado actualización

public partial class Client : ICopyToMe<Client> 

El método CopyToMe se hereda de una interfaz

public interface ICopyToMe<T> 
    { 
     void CopyToMe(T theObject); 
    } 

también la clase ha GetHashCode anulado

public override int GetHashCode() 
{ 
    int retVal = 13^ID^name.GetHashCode(); 
    return retVal; 
} 

e igual a

public override bool Equals(object obj) 
{ 
    bool retVal = false; 
    Client c = obj as Client; 
    if (c != null) 
     if (c.ID == this.ID && c._name == this._name) 
      retVal = true; 
    return retVal; 
} 

el método de actualización en la clase parcial

public void UpdateSingle() 
     {   
      L2SDataContext dc = new L2SDataContext(); 
      Client c = dc.Clients.Single<Client>(p => p.ID == this.ID); 
      c.CopyToMe(this); 
      c.updatedOn = DateTime.Now; 

      dc.SubmitChanges(); 
      dc.Dispose(); 
         } 

El método CopytoMe

public void CopyToMe(Client theObject) 
     { 
      ID = theObject.ID; 
      name = theObject.name;     
     } 

Im teniendo un cliente que fue seleccionada, cambiando su nombre y luego llamar a este método de actualización. el SQL generado es el siguiente

exec sp_executesql N'UPDATE [dbo].[tblClient] 
SET 
WHERE ([ID] = @p0) AND ([name] = @p1) AND ([insertedOn] = @p2) AND ([insertedBy] = @p3) AND ([updatedOn] = @p4) AND ([updatedBy] = @p5) 
AND ([deletedOn] IS NULL) AND ([deletedBy] IS NULL) AND (NOT ([deleted] = 1))',N'@p0 int,@p1 varchar(8000),@p2 datetime,@p3 int,@p4 
datetime,@p5 int',@p0=103,@p1='UnitTestClient',@p2=''2010-05-17 11:33:22:520'',@p3=3,@p4=''2010-05-17 11:33:22:520'',@p5=3 

no tengo ni idea de por qué esto no está funcionando ... se usa este tipo de

elija objeto -> campo de juego al nuevo valor -> envíe el seleccionado objeto

patrón muchas veces y no tenía este problema. tampoco hay nada obviamente incorrecto con el dbml - aunque esto es probablemente una declaración falsa

alguna idea?

Este problema hace que parezca que voy a tener que volver a ADO.Net, lo que me entristece.

Respuesta

1

OK después de algunas discusiones con algunas personas muy útiles de Microsoft he encontrado la respuesta a este problema.

Linq usa el código Hash para indexar sus colecciones en una tabla hash. Esto significa que la función del código hash debe funcionar solo en los campos que identifican de manera única el objeto.

En este caso, el Hash solo puede funcionar en la columna ID. Como tal GetHashCode siempre devolverá el mismo valor para los registros con la misma clave principal, incluso si sus datos son diferentes.

Igual que por otro lado puede probar a través de un mayor número de campos, es decir, su prueba es más específica que las comparaciones GetHashCode.

Si hace que la función GetHashCode cubra más campos que las claves primarias, linq2sql perderá la pista del objeto y se comportará de manera muy extraña.

+0

¡Perfecto! ¡Hice exactamente lo mismo y encontré esta respuesta aquí! ¡Gracias! – Ergodyne

0

Si esa declaración exacta de ACTUALIZACIÓN se envía a la base de datos (sin ningún argumento SET), entonces encontró un error en LINQ to SQL. Pruebe su código en .NET 4.0 y si aún falla, envíe un error al sitio de conexión de Microsoft.

+0

+1. No detecté que la consulta no era válida. Realmente no entendía lo que el OP estaba preguntando. – Steven

+0

esto es .net 4.0 ... extrañé ese pequeño detalle insignificante ... he tomado este código de un proyecto de 3.5 que estaba convirtiendo ... estoy 99.99% seguro de que este código funcionó perfectamente bien entonces. –

+0

sin embargo, agregué las anulaciones desde entonces, razón por la cual está roto. –

Cuestiones relacionadas