带有 XML 数据库字段的 Linq-to-SQL —— 为啥会这样?
Posted
技术标签:
【中文标题】带有 XML 数据库字段的 Linq-to-SQL —— 为啥会这样?【英文标题】:Linq-to-SQL With XML Database Fields -- Why does this work?带有 XML 数据库字段的 Linq-to-SQL —— 为什么会这样? 【发布时间】:2010-10-15 22:37:25 【问题描述】:一些背景知识:我有一个数据库,我想使用 linq-to-sql 通过 C# 应用程序进行更新。此表中的一列具有 XML 数据类型。
该表中的所有其他列(不是 XML 数据类型)更新得非常好,但是当我对 XML 字段进行更改时,程序(看似)正确执行,但该字段始终保留其原始运行SubmitChanges()
后的值。
我在网上找了几篇关于Microsoft Connect 诊断类似问题的帖子,最后偶然发现了解决方案here:
要强制更新 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 没有” t 处理 XElement.Changed 事件”。
对于我的实现,有效的代码最终看起来像这样:
MyXElementProperty.SetElementValue("Author", author);
MyXElementProperty = new XElement(MyXElementProperty);
作为参考(给发现此问题的任何其他人),以下内容也适用:
MyXElementProperty = new XElement(MyXElementProperty);
MyXElementProperty.SetElementValue("Author", author);
【问题讨论】:
【参考方案1】:当您将其设为新的XElement
时,您将创建一个不同的对象。有可能使用引用相等来检测“陈旧”,这显然会将其视为一个新值。
您实际上是在什么时候对元素进行更改?我期望 LINQ to SQL 拥有原始值的缓存副本,然后将其与新值进行比较。如果它只是通过复制引用来获取“缓存副本”,那么无论您对该对象做什么,它都会认为两者是相等的。相反,如果您创建一个 new 元素,然后更改 that,则旧对象仍将具有旧值,因此比较将了解您已进行更改。这有意义吗?
【讨论】:
已更新,希望能解决您的问题。不过,总的来说,你的解释是有道理的。 那么您是在在您进行更改之后设置属性吗?老实说,我有点惊讶它的工作原理......我希望它有同样的问题。也许它真的只是使用引用相等。 其实我只是在更改顺序后尝试过,两种方法似乎都可以。不确定这是否会让它或多或少令人困惑。 我怀疑这只是意味着它使用了引用相等性。【参考方案2】:这是一个非常“不同”的解决方法,我花了一段时间试图弄清楚为什么数据库上的 XML 字段没有上传。新的 XElement(updatedXElement) 也对我有用!
【讨论】:
以上是关于带有 XML 数据库字段的 Linq-to-SQL —— 为啥会这样?的主要内容,如果未能解决你的问题,请参考以下文章
如何在LINQ-To-SQL中排除Contex.InsertOnSubmit()上的用户定义字段?