2015-12-10 81 views
0

我在使用ServiceStack.Text(來自Nuget.org)將數據集序列化爲json時遇到了麻煩。我正在使用最新的穩定版本4.0.50VS 2015。我不斷收到ServiceStack.Text:將DataSet序列化爲json

過程被終止由於StackOverflowException

我的代碼:

using System; 
using System.Data; 
using System.Data.SqlClient; 
using ServiceStack.Text; 

namespace TestServiceStackText 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string ConnectionString = @"Server=MyServer; Database=NORTHWND; User Id=SomeUser; Password=SomePassword;"; 
      string SqlQuery = @"SELECT TOP 1 * FROM [NORTHWND].[dbo].[Customers]"; 

      // Create new dataset instance 
      DataSet dataset = new DataSet(); 

      // Fill it with a little data: 1 table, 1 row 
      using (var conn = new SqlConnection()) 
      { 
       using (var da = new SqlDataAdapter()) 
       { 
        using (da.SelectCommand = conn.CreateCommand()) 
        { 
         da.SelectCommand.CommandText = SqlQuery; 
         da.SelectCommand.Connection.ConnectionString = ConnectionString; 
         da.Fill(dataset); 
        } 
       } 
      } 

      // Serialize to json: exception occurs here 
      string json = TypeSerializer.SerializeToString<DataSet>(dataset); 
      Console.WriteLine("Dataset serialized to json:\n {0}", json); 

      // Deserialize to DataSet 
      DataSet ds = TypeSerializer.DeserializeFromString<DataSet>(json); 
      Console.WriteLine("Name: {0}, Nr. of Tables: {1}", ds.DataSetName, ds.Tables.Count); 
     } 
    } 
} 

建議任何人?

+2

我懷疑自己是在'DataSet'循環依賴和servicestack會繼續努力,即使它已經連載之前他們連載所有的屬性。 – sQuir3l

回答

2

沒有一個ServiceStack的文本序列化器對DataSet的顯式支持,這對於序列化來說是一種可怕的類型。

微ORM的喜歡OrmLite最終被更清潔和更容易使用它映射到clean POCO's that are ideal for serialization,如您上面的查詢等價代碼是:

var customers = Db.Select<Customer>(q => q.Take(1)); 

var json = customers.ToJson(); 
var dto = json.FromJson<Customer>(); 

或者,如果你不希望創建一個客戶類型可以使用OrmLite's dynamic API's映射到對象的類型化輸名單:

var list = Db.Select<List<object>>(
    "SELECT TOP 1 * FROM [NORTHWND].[dbo].[Customers]"); 

或字典:

var dict = Db.Select<Dictionary<string,object>>(
    "SELECT TOP 1 * FROM [NORTHWND].[dbo].[Customers]"); 

檢出northwind.servicestack.net項目,查看使用OrmLite和AutoQuery查詢Northwind數據集的代碼示例。

總之,如果您使用乾淨的POCO而不是每個序列化程序支持的DataSets,它們比DataSet小得多,速度也快,您還可以將POCO或寬鬆類型的Dictionary序列化爲CSV與ServiceStack.Text:

var csv = customers.ToCsv(); 
var csv = dict.ToCsv(); 
+0

以上所有內容都很合理,但我選擇數據集作爲我的DTO,因爲我需要它是完全通用的。在我的項目中,每次查詢都會有所不同,因此DTO必須處理該問題,並且在需要反序列化的WCF客戶端的接收端上爲已知類型。 但是,我注意到序列化/反序列化數據集是一個昂貴的操作。我目前使用的是Newtonsoft.Json,而且我正在尋找比目前更好的DTO和/或更快的串行器組件。 –

+0

@ErikB這也是動態API允許你做的事情。 Note DataSet已被棄用,並且沒有計劃將它們添加到CoreCLR。它們是一個沉重而複雜的數據結構,對於序列化來說是一個糟糕的選擇。我建議轉向清理POCO或泛型集合,這些集合可以更好地互操作,不會有太大的侷限性,並且將來會減少問題的發生。 – mythz