2009-03-27 6 views
10

Algunos antecedentes: Tengo una base de datos que quiero usar linq-to-sql para actualizar a través de una aplicación C#. Una de las columnas en esta tabla tiene un tipo de datos XML.Linq-to-SQL con campos de base de datos XML - ¿Por qué funciona esto?

Cada otra columna en esa tabla (que no es de un tipo de datos XML) se actualiza perfectamente, pero cuando fui a hacer cambios al campo XML, el programa se ejecuta (aparentemente) correctamente, pero el campo siempre conserva su valor original después de ejecutar SubmitChanges().

Miré alrededor de la Internet y encontré un par de mensajes en Microsoft Connect diagnosticar problemas similares y, finalmente encontré con la solución here:

Para forzar actualización de campo XML esto no va a hacer:

XElement tmp = MyLinqObject.XmlField; 
MyLinqObject.XmlField = null; 
MyLinqObject.XmlField = tmp; 

en lugar de eso para empujar LINQ para actualizar la columna XML asignar un objeto clonado:

MyLinqObject.XmlField = new XElement (MyLinqObject.XmlField); 

puedo confirmar que parece que en efecto a WOR k, pero no estoy exactamente seguro de por qué. Mi única suposición es que la Propiedad XmlField tiene algún tipo de identificador único en el montón y que al hacer un clon, le ha asignado un nuevo identificador único. Cuando Linq genera la consulta, ni siquiera intenta ver si el campo se ha actualizado, ya que tiene una nueva identificación, simplemente escribe el valor en la base de datos. Pero, simplemente estoy especulando y espero que alguien más pueda proporcionar una mejor comprensión de lo que está sucediendo detrás de escena.

EDITAR: Para abordar el post de Jon, el motivo de la emisión (como se explica en el sitio MS Connect) es que "el campo XML no se actualiza porque LINQ to SQL no maneja el XElement .Cambio de eventos ".

Por mi aplicación, el código que funciona termina buscando algo como esto:

MyXElementProperty.SetElementValue("Author", author); 

MyXElementProperty = new XElement(MyXElementProperty); 

Como referencia (a cualquier otra persona que encuentra esta pregunta), el siguiente también funciona:

MyXElementProperty = new XElement(MyXElementProperty); 

MyXElementProperty.SetElementValue("Author", author); 

Respuesta

10

Cuando lo convierte en un nuevo XElement, está creando un objeto diferente. Es posible que para detectar "estancamiento" esté usando igualdad de referencia, lo que obviamente trataría esto como un nuevo valor.

¿En qué punto está realmente haciendo cambios en el elemento? Me gustaría esperar LINQ to SQL para tener una copia en caché del valor original, y luego comparar eso con el nuevo valor. Si está tomando esa "copia en caché" simplemente copiando la referencia, entonces haga lo que haga con ese objeto, siempre pensará que los dos son iguales. Si, en cambio, crea un elemento nuevo, y luego cambia ese, entonces el objeto antiguo seguirá teniendo el valor anterior, por lo que la comparación comprenderá que ha realizado cambios. ¿Tiene sentido?

+0

Se actualizó para responder a sus preguntas con suerte. En general, tu explicación tiene sentido, sin embargo. – jerhinesmith

+1

¿Está configurando la propiedad * después de * que ha realizado el cambio? Estoy un poco sorprendido de que funcione, para ser sincero ... esperaría que tenga el mismo problema.Tal vez solo sea usar igualdad de referencia. –

+0

En realidad, lo intenté después de cambiar el orden y ambas formas parecen funcionar. No estoy seguro de si eso lo hace más o menos confuso. – jerhinesmith

0

Esta fue una solución muy 'diferente', pasé un tiempo tratando de descubrir por qué el campo XML en la base de datos no se cargaba. ¡The New XElement (updatedXElement) también funcionó para mí!

Cuestiones relacionadas