8

我正在为 WCF 服务开发一种“存储和转发”应用程序。我想将消息作为原始 XML blob 保存在数据库中,如 XElement。我在将 datacontract 转换为数据库调用所需的 XElement 类型时遇到了一些麻烦。有任何想法吗?

4

5 回答 5

12

这会将其作为字符串返回,您可以将其放入 db 到 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 to sql 吗?我问的原因是因为您问题的 XElement 部分。如果是这种情况,您可以在 .dbml 设计器中修改它以使用字符串作为 CLR 类型,而不是默认的 XElement。

于 2009-07-03T04:37:51.267 回答
9

投票最多的答案(Jason W. 发布)对我不起作用。我不知道为什么这个答案得票最多。但是在四处寻找之后我发现了这个

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;
}
于 2010-12-01T18:48:07.760 回答
2

如果您的数据库是 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();
                }
            }
        }
    }
}
于 2009-07-06T18:25:24.987 回答
1

我不确定将其传输到 XElement 的最有效方法,但要将其传输到字符串只需运行:

DataContractSerializer serializer = new DataContractSerializer(typeof(Foo));
using (MemoryStream memStream = new MemoryStream())
{
    serializer.WriteObject(memStream, fooInstance);
    byte[] blob = memStream.ToArray();
}
于 2009-07-03T04:32:56.690 回答
1

我尝试使用使用 StringBuilder 的 Jason w'Serialize 函数,但它为具有 [DataContract()] 属性的 LingToSQL Designer 生成的表类返回空字符串

但是,如果我按照 AgileJon 的建议序列化为字节数组

然后使用 UTF7Encoding 转换为 string ,它创建可读的 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 解决方案不起作用。

于 2010-03-11T07:07:23.880 回答