У меня есть метод, который возвращает хорошо сформированную строку Xml . Как передать эту строку в SqlXml?
Как передать строку в SqlXml
Ответ 1
В SQL Server просто: CAST(MyVarcharString AS xml)
Или назначьте его SQLDbType.Xml в .net как, скажем, параметр
Ответ 2
Другой способ в чистом С# - для потомков:
using (var memoryStream = new MemoryStream())
{
using (var xmlWriter = XmlWriter.Create(memoryStream))
{
xmlWriter.WriteString(xmlData.ToString().Trim());
return new System.Data.SqlTypes.SqlXml(memoryStream);
}
}
Ответ 3
Это моя версия метода преобразования С#.
public static SqlXml ConvertString2SqlXml(string xmlData)
{
UTF8Encoding encoding = new UTF8Encoding();
MemoryStream m = new MemoryStream(encoding.GetBytes(xmlData));
return new SqlXml(m);
}
Мне не очень нравится, потому что мне хотелось бы иметь MemoryStream с использованием блока, но это дало мне:
Невозможно получить доступ к удаленному объекту. Имя объекта: "Неверная попытка вызова Читайте, когда поток закрыт. '.
Я готов принять эту проблему, потому что этот код используется только в модульных тестах, где я хочу протестировать SqlFunction с параметром SqlXml, который будет развернут в CLR SQL Server.
Ответ ReinhardtB не помог мне, из-за следующих проблем:
Когда вы вызываете это с помощью xmlData "<?xml version=\"1.0\" encoding=\"utf-8\"?><test></test>"
(обратные косые черты находятся в строковом литерале С#), я получил:
Исправлено System.InvalidOperationException Message = Token Text в состоянии Start приведет к недопустимому XML-документу. Убедитесь, что для параметра ConformanceLevel установлено значение ConformanceLevel.Fragment или ConformanceLevel.Auto, если вы хотите напишите фрагмент XML.
Это было легко исправлено с помощью следующей модификации:
XmlWriterSettings settings = new XmlWriterSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (var xmlWriter = XmlWriter.Create(memoryStream, settings))
Однако это привело к следующему исключению:
Возникло событие System.ObjectDisposedException Сообщение = Не удается получить доступ к расположенный объект. Имя объекта: "Неверная попытка вызова Чтение, когда поток закрыт. '. Источник = System.Datap >
Это я мог бы обойти, опуская блок использования для MemoryStream (что, конечно же, плохая идея), просто чтобы попасть в следующую проблему: при проверке значения SqlXml, SqlXml.Value, я обнаружил, что это содержит значение <?xml version="1.0" encoding="utf-8"?><test></test>
, то есть < и > сбежали! Это выглядит как серьезная проблема с типом SqlXml
.
Ответ 4
Я знаю, что на это ответили, но ни один из ответов не работал у меня. Вместо этого я сделал другой подход, используя этот oneliner
var sqlXml = new SqlXml(new XmlTextReader(new StringReader(stringToParseToSqlXml)));
Однако это протекает, но меняет его на:
using (var reader = new StringReader(stringToParseToSqlXml))
{
using (var xmlreader = new XmlTextReader(reader))
{
var sqlXml = new SqlXml(xmlreader);
// Do other stuff
}
}
Я использовал это, и, похоже, это работает для меня.
Ответ 5
SqlParameter отлично работает, если вы задали правильную длину.
comm.Parameters.Add("@XML_Field", SqlDbType.Xml, stringXml.Length)
comm.Prepare()
comm.Parameters("@XML_Field").Value = stringXml
И -1, если вы хотите установить DBNull.Value в некоторых случаях:
comm.Parameters.Add("@XML_Field", SqlDbType.Xml, -1)
comm.Prepare()
comm.Parameters("@XML_Field").Value = DBNull.Value