使用XML数据库字段的Linq-to-SQL – 为什么这样做?

一些背景:我有一个数据库,我想使用linq-to-sql通过C#应用程序进行更新。 此表中的一列具有XML数据类型。

该表中的每个其他列(不是XML数据类型)都可以完美地更新,但是当我对XML字段进行更改时,程序(看似)正确执行,但是在我之后字段始终保留其原始值运行SubmitChanges()

我浏览了互联网,发现Microsoft Connect上的一些post诊断出类似问题,最后在这里偶然发现了解决方案:

要强制XML字段更新,这不会:

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

而不是强迫LINQ更新XML列分配克隆对象:

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

我可以确认这似乎确实有效,但我不确定为什么。 我唯一的猜测是XmlField属性在堆上有某种唯一标识符,通过制作克隆,你已经为它分配了一个新的唯一标识符。 当Linq然后生成查询时,它甚至不会尝试查看该字段是否已更新,因为它有一个新的id,它只是将值写入数据库。 但是,我只是在猜测并希望其他人能够更好地了解幕后发生的事情。

编辑 :为了解决Jon的post,问题的原因(正如在MS Connect网站上解释的那样)是“XML字段不会更新,因为Linq-to-SQL不处理XElement.Changed事件”。

对于我的实现,工作的代码最终看起来像这样:

 MyXElementProperty.SetElementValue("Author", author); MyXElementProperty = new XElement(MyXElementProperty); 

作为参考(对于发现此问题的任何其他人),以下内容也有效:

 MyXElementProperty = new XElement(MyXElementProperty); MyXElementProperty.SetElementValue("Author", author); 

当你把它作为一个新的XElement ,你正在制作一个不同的对象。 有可能使用引用相等来检测“陈旧性”,这显然会将其视为新值。

你到底在什么时候对元素进行了更改? 我希望 LINQ to SQL能够获得原始值的缓存副本,然后将其与新值进行比较。 如果只是通过复制引用来获取“缓存副本”,那么无论你对该对象做什么,它总会认为两者是相等的。 如果您创建一个元素,然后更改 ,那么旧对象仍将具有旧值,因此比较将理解您已进行更改。 那有意义吗?

这是一个非常“不同”的解决方法,我花了一段时间试图弄清楚为什么数据库上的XML字段没有上传。 New XElement(updatedXElement)也适合我!