2009-07-03 13 views
8

Tôi đang làm việc trên một loại "lưu trữ và chuyển tiếp" ứng dụng cho các dịch vụ WCF. Tôi muốn lưu tin nhắn trong cơ sở dữ liệu dưới dạng blob XML thô, như XElement. Tôi đang gặp một chút rắc rối khi chuyển đổi datacontract thành kiểu XElement mà tôi cần cho cuộc gọi cơ sở dữ liệu. Ý tưởng nào?Persist một DataContract như XML trong một cơ sở dữ liệu

+1

XElement là không giống như "blob xml thô". Trước đây là một loại, tiện dụng để làm điều này với XML. Khác là một chuỗi với một định dạng cụ thể. Bạn có thể lưu từ bất kỳ loại nào được trang trí với [DataContract] thành chuỗi XML. (Xem bên dưới để biết ví dụ). XElement - bạn có thể ngồi đó trên credenza của bạn, bạn không cần nó. – Cheeso

Trả lời

12

này trả về nó như là một chuỗi, mà bạn có thể đưa vào db vào một cột xml. Đây là một phương pháp chung tốt mà bạn có thể sử dụng để tuần tự hóa các datacontracts.

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(); 
} 

btw, bạn đang sử dụng LINQ to sql? Lý do tôi hỏi là vì phần XElement của câu hỏi của bạn. nếu đó là trường hợp, bạn có thể sửa đổi điều này trong các nhà thiết kế .dbml để sử dụng một chuỗi như là loại CLR, và không phải là XElement mặc định.

+0

Điều này không hiệu quả đối với tôi. Xem câu trả lời của user224125 dưới đây. –

1

Tôi không chắc chắn về cách thức hiệu quả nhất để làm cho nó một XElement, nhưng để làm cho nó một chuỗi chỉ cần chạy:

DataContractSerializer serializer = new DataContractSerializer(typeof(Foo)); 
using (MemoryStream memStream = new MemoryStream()) 
{ 
    serializer.WriteObject(memStream, fooInstance); 
    byte[] blob = memStream.ToArray(); 
} 
2

Nếu cơ sở dữ liệu của bạn là SQL Server 2005 trở lên, bạn có thể sử dụng các kiểu dữ liệu 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(); 
       } 
      } 
     } 
    } 
} 
1

Tôi cố gắng để sử dụng Jason w'Serialize chức năng sử dụng StringBuilder, nhưng nó sẽ trả về chuỗi rỗng cho LingToSQL thiết kế lớp bảng tạo với [DataContract()] thuộc tính

Tuy nhiên nếu tôi serialze để mảng byte theo đề nghị của AgileJon

và sau đó sử dụng UTF7Encoding để chuyển sang chuỗi, nó tạo ra chuỗi XML có thể đọc được.

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; 
    } 

Không chắc chắn tại sao giải pháp stringBuilder không hoạt động.

8

Được bỏ phiếu nhiều nhất trên câu trả lời (Jason W. đã đăng) không hoạt động đối với tôi. Tôi không biết tại sao câu trả lời đó lại có nhiều phiếu bầu nhất. Nhưng sau khi tìm kiếm xung quanh, tôi thấy điều này

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

Làm việc cho dự án của tôi. Tôi chỉ có một vài lớp và đặt các thuộc tính datacontract và datamemeber trên các lớp và các thuộc tính và sau đó muốn lấy một chuỗi XML mà tôi có thể ghi vào cơ sở dữ liệu.

Mã từ liên kết ở trên trong trường hợp nó đi 404:

serializes:

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(); 
} 

Deserializes:

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; 
} 
+0

Cảm ơn bạn đã liên kết. –

Các vấn đề liên quan