Этот вопрос является почти дубликатом двух других, и удивительно - хотя этот вопрос является самым последним - я считаю, что ему не хватает лучшего ответа.
Дубликаты и, как я считаю, их лучшие ответы:
В конце концов, не имеет значения, какая кодировка объявлена или используется, если XmlReader
может анализировать ее локально на сервере приложений.
Как было подтверждено в Самый эффективный способ чтения XML в ADO.net из столбца типа XML на сервере SQL? , SQL Server хранит XML в эффективном двоичном формате. Используя класс SqlXml
, ADO.net может взаимодействовать с SQL Server в этом двоичном формате и не требовать от сервера базы данных какой-либо сериализации или десериализации XML. Это также должно быть более эффективным для транспортировки по сети.
Используя SqlXml
, XML будет отправляться предварительно проанализированным в базу данных, а затем БД не нужно ничего знать о кодировках символов - UTF-16 или иным образом. В частности, обратите внимание, что объявления XML даже не сохраняются с данными в базе данных, независимо от того, какой метод используется для их вставки.
Пожалуйста, обратитесь к приведенным выше ответам для методов, которые выглядят очень похоже на это, но этот пример мой:
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.IO;
using System.Xml;
static class XmlDemo {
static void Main(string[] args) {
using(SqlConnection conn = new SqlConnection()) {
conn.ConnectionString = "...";
conn.Open();
using(SqlCommand cmd = new SqlCommand("Insert Into TestData(Xml) Values (@Xml)", conn)) {
cmd.Parameters.Add(new SqlParameter("@Xml", SqlDbType.Xml) {
// Works.
// Value = "<Test/>"
// Works. XML Declaration is not persisted!
// Value = "<?xml version=\"1.0\"?><Test/>"
// Works. XML Declaration is not persisted!
// Value = "<?xml version=\"1.0\" encoding=\"UTF-16\"?><Test/>"
// Error ("unable to switch the encoding" SqlException).
// Value = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Test/>"
// Works. XML Declaration is not persisted!
Value = new SqlXml(XmlReader.Create(new StringReader("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Test/>")))
});
cmd.ExecuteNonQuery();
}
}
}
}
Обратите внимание, что я бы не считал последний (некомментированный) пример "готовым к производству", но оставил его как есть, чтобы быть кратким и читабельным. Если все сделано правильно, и StringReader
, и созданный XmlReader
должны быть инициализированы в операторах using
, чтобы гарантировать, что их методы Close()
будут вызваны после завершения.
Из того, что я видел, объявления XML никогда не сохраняются при использовании столбца XML. Например, даже без использования .NET и только с использованием этого прямого оператора вставки SQL объявление XML не сохраняется в базе данных с XML:
Insert Into TestData(Xml) Values ('<?xml version="1.0" encoding="UTF-8"?><Test/>');
Теперь, с точки зрения вопроса OP, сериализуемый объект все еще должен быть преобразован в структуру XML из объекта MyMessage
, и для этого все еще необходим XmlSerializer
. Однако в худшем случае вместо сериализации в строку, сообщение можно вместо этого сериализовать в XmlDocument
, который затем может быть передан в SqlXml
через новый XmlNodeReader
, избегая Сериализация / сериализация поездки в строку. (См. http://blogs.msdn.com/b/jongallant/archive/2007/01/30/how-to-convert-xmldocument-to-xmlreader-for-sqlxml-data-type.aspx для деталей и примера.)
Все здесь было разработано и протестировано с .NET 4.0 и SQL Server 2008 R2.
Пожалуйста, не тратьте впустую , выполняя XML посредством дополнительных преобразований (десериализация и сериализация - в DOM, строки или иным образом), как показано в других ответах здесь и в других местах.