locked
Linq to SQL XML fields don't update

    Question

  • I'm going to post my question again because I think my first post was moved to the off-topic board by error.

    If this really isn't where I should be asking this question, can a moderator or someone else please tell me where I should ask this question?


    When I change an XElement field in a Linq to SQL class and call SubmitChanges on the data context, it doesn't update. Linq to SQL seems to just flat out ignore XElement's change notifications.

    I tried a workaround where whenever the property changed I would null the XElement field and then set it again, but that doesn't work either.

    Is this a bug?

    Are there any viable workarounds?

    Thanks in advance,

    Rei

    Thursday, July 24, 2008 7:00 PM

Answers

  • That will still not work. 

     

    LINQ to SQL only understands changes by comparing the current and original values of data fields. When you first modify an entity, L2S makes a backup copy of the entity by copying all the field values into a new object instance. It does not do a deep copy, so values like XElements are copied over by reference. L2S treats all valus in fields as immutable, therefore the value is only ever considered changed for a reference type if the reference has actually changed. In your example, the XElement itself never changes but its contents do. L2S will not see the difference, since both current and original values of the field refer to the same XElement instance.

     

    The same problem exists if you model binary data using a byte array.  Since an array is mutable, if you change the contents of the array without changing the array itself, L2S will not see it.

     

    The solution is to create an entirely new XElement object (based on the original) and assign it to the field in the entity.

    Tuesday, September 02, 2008 3:56 PM

All replies

  • Sorry for late reply. There is an issue with LINQ To SQL - I does not recognise internal changes to an XElement, e.g.

     

    Code Snippet

    var dc = new Datacontext();

    var record = dc.MyTable.First();

    // modify xml

    record.XML.Add(new XElement("newelement"));

    dc.SubmitChanges();

     

     

     

     

    will not change the XML. Instead try

     

    Code Snippet

    var dc = new Datacontext();

    var record = dc.MyTable.First();

    var xml = record.XML;

    // modify xml

    xml.Add(new XElement("newelement"));

    record.XML = xml;

    dc.SubmitChanges();

     

     

    Tuesday, September 02, 2008 1:57 PM
  • That will still not work. 

     

    LINQ to SQL only understands changes by comparing the current and original values of data fields. When you first modify an entity, L2S makes a backup copy of the entity by copying all the field values into a new object instance. It does not do a deep copy, so values like XElements are copied over by reference. L2S treats all valus in fields as immutable, therefore the value is only ever considered changed for a reference type if the reference has actually changed. In your example, the XElement itself never changes but its contents do. L2S will not see the difference, since both current and original values of the field refer to the same XElement instance.

     

    The same problem exists if you model binary data using a byte array.  Since an array is mutable, if you change the contents of the array without changing the array itself, L2S will not see it.

     

    The solution is to create an entirely new XElement object (based on the original) and assign it to the field in the entity.

    Tuesday, September 02, 2008 3:56 PM
  • Sorry, yes it should have been

    Code Snippet

    var dc = new Datacontext();

    var record = dc.MyTable.First();

    var xml = record.XML;

    // modify xml

    xml.Add(new XElement("newelement"));

    record.XML = new XElement(xml);

    dc.SubmitChanges();

     

     

    Tuesday, September 02, 2008 4:02 PM
  • Strange. I sincerely hope this is being considered a bug, because if it's not, then there's something more fundamentally wrong.

     

    XElement certainly isn't comparable to an array -- arrays don't offer change notifications; XElement does. I also don't see any side effects that subscribing to XElement.Changed might cause.

     

    You'd think this would have been noticed and fixed before release, especially considering how un-obvious the workaround is.

     

    After all, Linq to SQL and Linq to XML were made at the same time and largely by the same people. I see no reason why the two projects should be so horribly discoordinated.

     

    Thanks for the response and sorry for ranting; I just really needed to get that off my chest.

    Tuesday, September 02, 2008 9:47 PM
  • I completely agree with Rei Miyasaka.  This is a terrible implementation.  This bug has cost me a great deal of time.  It completly defies logic.
    Wednesday, July 13, 2011 7:22 PM