代码之家  ›  专栏  ›  技术社区  ›  Robert

将DataContract作为XML持久化到数据库中

  •  8
  • Robert  · 技术社区  · 17 年前

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

    5 回复  |  直到 17 年前
        1
  •  12
  •   jasonmw    17 年前

    这将以字符串的形式返回,您可以将其放入数据库的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();
    }
    

        2
  •  9
  •   Evan Larsen    13 年前

    http://billrob.com/archive/2010/02/09/datacontractserializer-converting-objects-to-xml-string.aspx

    序列化:

    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;
    }
    
        3
  •  2
  •   John Saunders    17 年前

    如果数据库是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();
                    }
                }
            }
        }
    }
    
        4
  •  1
  •   AgileJon    17 年前

    DataContractSerializer serializer = new DataContractSerializer(typeof(Foo));
    using (MemoryStream memStream = new MemoryStream())
    {
        serializer.WriteObject(memStream, fooInstance);
        byte[] blob = memStream.ToArray();
    }
    
        5
  •  1
  •   Michael Freidgeim    16 年前

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

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

    然后使用UTF7编码转换为字符串,它创建可读的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解决方案不起作用。