Вопрос

Я работаю над своего рода приложением «хранения и пересылки» для служб 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 не работает.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top