一些背景:我有一个数据库,我想使用linq-to-sql通过C#应用程序进行更新.此表中的一列具有XML数据类型.
该表中的每个其他列(不是XML数据类型)都可以完美地更新,但是当我对XML字段进行更改时,程序(看似)正确执行,但是在我之后字段始终保留其原始值跑SubmitChanges()
.
我浏览了一下互联网,发现Microsoft Connect上的一些帖子诊断出类似的问题,最后在这里偶然发现了解决方案:
要强制XML字段更新,这不会:
XElement tmp = MyLinqObject.XmlField; MyLinqObject.XmlField = null; MyLinqObject.XmlField = tmp;
而不是强迫LINQ更新XML列分配克隆对象:
MyLinqObject.XmlField = new XElement (MyLinqObject.XmlField);
我可以确认这似乎确实有效,但我不确定为什么.我唯一的猜测是XmlField属性在堆上有某种唯一标识符,通过制作克隆,你已经为它分配了一个新的唯一标识符.当Linq然后生成查询时,它甚至不会尝试查看该字段是否已更新,因为它有一个新的id,它只是将值写入数据库.但是,我只是在猜测并希望其他人能够更好地了解幕后发生的事情.
编辑:为了解决Jon的帖子,问题的原因(正如在MS Connect网站上解释的那样)是"XML字段不会更新,因为Linq-to-SQL不处理XElement.Changed事件".
对于我的实现,有效的代码最终看起来像这样:
MyXElementProperty.SetElementValue("Author", author); MyXElementProperty = new XElement(MyXElementProperty);
作为参考(对于发现此问题的任何其他人),以下内容也有效:
MyXElementProperty = new XElement(MyXElementProperty); MyXElementProperty.SetElementValue("Author", author);
Jon Skeet.. 10
当你把它变成新的时XElement
,你就会制作一个不同的对象.有可能使用引用相等来检测"陈旧性",这显然会将其视为新值.
你到底在什么时候对元素进行了更改?我希望 LINQ to SQL具有原始值的缓存副本,然后将其与新值进行比较.如果只是通过复制引用来获取"缓存副本",那么无论你对该对象做什么,它总会认为两者是相等的.如果您创建一个新元素,然后更改它,那么旧对象仍将具有旧值,因此比较将理解您已进行了更改.那有意义吗?
当你把它变成新的时XElement
,你就会制作一个不同的对象.有可能使用引用相等来检测"陈旧性",这显然会将其视为新值.
你到底在什么时候对元素进行了更改?我希望 LINQ to SQL具有原始值的缓存副本,然后将其与新值进行比较.如果只是通过复制引用来获取"缓存副本",那么无论你对该对象做什么,它总会认为两者是相等的.如果您创建一个新元素,然后更改它,那么旧对象仍将具有旧值,因此比较将理解您已进行了更改.那有意义吗?