Как передать строку в SqlXml

У меня есть метод, который возвращает хорошо сформированную строку Xml . Как передать эту строку в 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.Data​​p >

Это я мог бы обойти, опуская блок использования для MemoryStream (что, конечно же, плохая идея), просто чтобы попасть в следующую проблему: при проверке значения SqlXml, SqlXml.Value, я обнаружил, что это содержит значение &lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;test&gt;&lt;/test&gt;, то есть < и > сбежали! Это выглядит как серьезная проблема с типом 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