Сохранение DataContract в виде XML в базе данных.
-
21-08-2019 - |
Вопрос
Я работаю над своего рода приложением «хранения и пересылки» для служб WCF.Я хочу сохранить сообщение в базе данных в виде необработанного XML-объекта, например XElement.У меня возникли некоторые проблемы с преобразованием контракта данных в тип XElement, который мне нужен для вызова базы данных.Есть идеи?
Решение
это возвращает его в виде строки, которую вы можете поместить в базу данных в столбец xml.Вот хороший общий метод, который можно использовать для сериализации контрактов данных.
public static string Serialize<T>(T obj)
{
StringBuilder sb = new StringBuilder();
DataContractSerializer ser = new DataContractSerializer(typeof(T));
ser.WriteObject(XmlWriter.Create(sb), obj);
return sb.ToString();
}
Кстати, вы используете linq для sql?Причина, по которой я спрашиваю, связана с частью вашего вопроса, касающейся XElement.в этом случае вы можете изменить это в конструкторе .dbml, чтобы использовать строку в качестве типа CLR, а не XElement по умолчанию.
Другие советы
Ответ, получивший наибольшее количество голосов (Джейсон В.опубликовал) у меня не сработало.Я не знаю, почему этот ответ получил наибольшее количество голосов.Но после поиска я нашел это
http://billrob.com/archive/2010/02/09/datacontractserializer-converting-objects-to-xml-string.aspx
Это сработало для моего проекта.У меня было всего лишь несколько классов, я поместил атрибуты datacontract и datamemeber в классы и свойства, а затем захотел получить строку XML, которую я мог бы записать в базу данных.
Код по ссылке выше, если выдается ошибка 404:
Сериализуется:
var serializer = new DataContractSerializer(tempData.GetType());
using (var backing = new System.IO.StringWriter())
using (var writer = new System.Xml.XmlTextWriter(backing))
{
serializer.WriteObject(writer, tempData);
data.XmlData = backing.ToString();
}
Десериализует:
var serializer = new DataContractSerializer(typeof(T));
using (var backing = new System.IO.StringReader(data.XmlData))
using (var reader = new System.Xml.XmlTextReader(backing))
{
return serializer.ReadObject(reader) as T;
}
Если ваша база данных — SQL Server 2005 или более поздней версии, вы можете использовать тип данных XML:
private readonly DataContractToSerialize _testContract =
new DataContractToSerialize
{
ID = 1,
Name = "One",
Children =
{
new ChildClassToSerialize {ChildMember = "ChildOne"},
new ChildClassToSerialize {ChildMember = "ChildTwo"}
}
};
public void SerializeDataContract()
{
using (var outputStream = new MemoryStream())
{
using (var writer = XmlWriter.Create(outputStream))
{
var serializer =
new DataContractSerializer(_testContract.GetType());
if (writer != null)
{
serializer.WriteObject(writer, _testContract);
}
}
outputStream.Position = 0;
using (
var conn =
new SqlConnection(Settings.Default.ConnectionString))
{
conn.Open();
const string INSERT_COMMAND =
@"INSERT INTO XmlStore (Data) VALUES (@Data)";
using (var cmd = new SqlCommand(INSERT_COMMAND, conn))
{
using (var reader = XmlReader.Create(outputStream))
{
var xml = new SqlXml(reader);
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@Data", xml);
cmd.ExecuteNonQuery();
}
}
}
}
}
Я не уверен насчет наиболее эффективного способа передать его в XElement, но чтобы передать его в строку, просто запустите:
DataContractSerializer serializer = new DataContractSerializer(typeof(Foo));
using (MemoryStream memStream = new MemoryStream())
{
serializer.WriteObject(memStream, fooInstance);
byte[] blob = memStream.ToArray();
}
Я попытался использовать функцию Jason W'serialize, которая использует StringBuilder, но он возвращает пустую строку для создания дизайнера LingtoSQL с атрибутом [dataContract ()]
Однако, если я сериализую в массив байтов, как предлагает AgileJon
а затем используйте UTF7Encoding для преобразования в строку, он создает читаемую строку XML.
static string DataContractSerializeUsingByteArray<T>(T obj)
{
string sRet = "";
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
using (MemoryStream memStream = new MemoryStream())
{
serializer.WriteObject(memStream, obj);
byte[] blob = memStream.ToArray();
var encoding= new System.Text.UTF7Encoding();
sRet = encoding.GetString(blob);
}
return sRet;
}
Не знаю, почему решение stringBuilder не работает.