Linq-to-SQL с полями базы данных XML - Почему это работает? - PullRequest
10 голосов
/ 27 марта 2009

Немного предыстории: у меня есть база данных, которую я хочу использовать 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 генерирует запрос, он даже не пытается увидеть, было ли поле обновлено, поскольку у него новый идентификатор, он просто записывает значение в базу данных. Но я просто размышляю и надеюсь, что кто-то еще сможет лучше понять, что происходит за кулисами.

РЕДАКТИРОВАТЬ : При рассмотрении сообщения Джона причина проблемы (как это объясняется на сайте MS Connect) заключается в том, что «поле XML не обновляется, поскольку Linq-to-SQL этого не делает. обработать событие XElement.Changed ".

Для моей реализации работающий код выглядит примерно так:

MyXElementProperty.SetElementValue("Author", author);

MyXElementProperty = new XElement(MyXElementProperty);

Для справки (любому, кто найдет этот вопрос), также работает следующее:

MyXElementProperty = new XElement(MyXElementProperty);

MyXElementProperty.SetElementValue("Author", author);

Ответы [ 2 ]

10 голосов
/ 27 марта 2009

Когда вы делаете его новым XElement, вы создаете другой объект. Вполне возможно, что для определения «устаревания» используется равенство ссылок, которое, очевидно, будет воспринимать это как новое значение.

В какой момент вы действительно вносите изменения в элемент? Я бы ожидал, что LINQ to SQL будет иметь кешированную копию исходного значения, а затем сравнить это с новым значением. Если он берет эту «кэшированную копию», просто копируя ссылку, то, что бы вы ни делали с этим объектом, он всегда будет думать, что они равны. Если вместо этого вы создадите новый элемент, а затем измените на , тогда старый объект все равно будет иметь старое значение, поэтому при сравнении вы поймете, что вы внесли изменения. Имеет ли это смысл?

0 голосов
/ 23 декабря 2010

Это был «другой» обходной путь, я потратил некоторое время, пытаясь выяснить, почему поле XML в базе данных не загружалось. Новый XElement (updatedXElement) работал и для меня!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...