Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
127 views
in Technique[技术] by (71.8m points)

c# - Linq-to-SQL With XML Database Fields -- Why does this work?

Some background: I have an database that I want to use linq-to-sql to update through a C# application. One of the columns in this table has an XML datatype.

Every other column in that table (that isn't of an XML datatype) updates perfectly fine, but when I went to make changes to the XML field, the program executes (seemingly) correctly, but the field always retains its original value after I run SubmitChanges().

I looked around the internet and found a few posts on Microsoft Connect diagnosing similar problems and finally stumbled on the solution here:

To force XML field update this won't do:

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

Instead of that to force LINQ to update XML column assign a cloned object:

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

I can confirm that this does indeed seem to work, but I'm not exactly sure why. My only guess is that the XmlField Property has some sort of unique identifier on the heap and that by making a clone, you've assigned it a new unique identifier. When Linq then generates the query, it doesn't even attempt to see if the field has been updated, since it has a new id, it simply write the value to the database. But, I'm simply speculating and hope that someone else can provide a better understanding of what is going on behind the scenes.

EDIT: To address Jon's post, the reason for the issue (as it is explained on the MS Connect site) is that "the XML field does not update because Linq-to-SQL doesn't handle the XElement.Changed event".

For my implementation, the code that works ends up looking something like this:

MyXElementProperty.SetElementValue("Author", author);

MyXElementProperty = new XElement(MyXElementProperty);

For reference (to anyone else that finds this question), the following also works:

MyXElementProperty = new XElement(MyXElementProperty);

MyXElementProperty.SetElementValue("Author", author);
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When you make it a new XElement, you're making a different object. It's possible that to detect "staleness" it's using reference equality, which would obviously treat this as a new value.

At what point are you actually making changes to the element? I would expect LINQ to SQL to have a cached copy of the original value, and then compare that with the new value. If it's taking that "cached copy" by just copying the reference, then whatever you do to that object, it will always think the two are equal. If instead you create a new element, and then change that, then the old object will still have the old value, so the comparison will understand that you've made changes. Does that make sense?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...