2009-07-03 20 views
8

WCF hizmetleri için bir tür "depola ve ilet" uygulaması üzerinde çalışıyorum. İletiyi bir veritabanında XElement olarak ham XML blob olarak kaydetmek istiyorum. Veri kontratını, veritabanı çağrısı için ihtiyacım olan XElement türüne dönüştürmede biraz sorun yaşıyorum. Herhangi bir fikir?DataContract veritabanında XML olarak devam et

+1

XElement "ham xml blob" aynı şey değildir. Eski, XML ile bunu yapmak için kullanışlı bir türdür. Diğeri, belirli bir biçime sahip bir dizedir. [DataContract] ile dekore edilmiş herhangi bir türden XML dizesine kaydedebilirsiniz. (Örnekler için aşağıya bakınız). XElement - bunu credenza'da oturabilirsin, buna ihtiyacın yok. – Cheeso

cevap

12

bu içine koyabilirsiniz bir dize olarak döndürür db bir xml sütununa. Veri kontekstlerini serileştirmek için kullanabileceğiniz iyi bir genel yöntem.

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, linq to sql kullanıyor musunuz? Sormamın nedeni, sorunuzun XElement bölümünden kaynaklanıyor. Bu durumda, .dbml tasarımcısında, bir dizeyi CLR türü olarak kullanmak için değiştirebilir ve varsayılan XElement'i değiştiremezsiniz. veritabanı SQL Server 2005 veya üzerinde ise

+0

Bu benim için çalışmadı. Aşağıdan kullanıcı224125'in cevabına bakınız. –

1

Bir XElement için bunu elde etmek için en etkili yol hakkında emin değilim, ama bir dizeye almak için sadece çalıştırın:

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

, XML veri türünü kullanabilirsiniz:

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

ben StringBuilder kullanan Jason w'Serialize işlevini kullanmaya çalıştı ama LingToSQL Designer için boş bir dize döndürür [DataContract()]

bağlıyor Ancak AgileJon

önerdiği ve daha sonra dizeye dönüştürmek için UTF7Encoding kullanmak gibi bayt dizisine serialze eğer, yarattığı okunabilir XML dizesiyle oluşturulan tablo sınıfı .

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

Neden StringBuilder çözümünün çalışmadığından emin değil.

8

En çok oylanan cevap (Jason W. yayınlanmıştır) benim için çalışmadı. Bu cevabın neden en çok oyu aldığını bilmiyorum. Ama etrafında arama yaptıktan sonra Projem için çalıştı bu

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

bulundu. Sadece birkaç sınıfım vardı ve veri kontratı ve datamemeber özelliklerini sınıflar ve özellikler üzerine koyup veritabanına yazabileceğim bir XML dizisi almak istedim. o 404 gider yukarıdaki örtmek bağlantıdan

Kodu:

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

Bağlantı için teşekkürler. –

İlgili konular