2014-02-12 108 views
3

我想轉換其中包含多個數據表的數據集。將具有多個數據表的數據集轉換爲Json

以下爲例子,

數據集X有兩個數據表A和B

Dataset

我想要的結果如下,

{ 
    "type":"A", 
    "value":"100", 
    "details":[ 
     {"name":"John", "age":"45", "gender":"M"}, 
     {"name":"Sebastin", "age":"34", "gender":"M"}, 
     {"name":"Marc", "age":"23", "gender":"M"}, 
     {"name":"Natalia", "age":"34", "gender":"F"} 
     ] 
} 

目前我使用Newtonsoft.Json。 Newtonsoft.Json有可能嗎? 如果沒有,是否可以使用任何其他.net Json工具?

+0

datatable A和dataset.Tables [1]爲datatable B –

回答

5

您可以通過實現自定義JsonConverter爲DataSet這樣得到你想要的JSON:

class CustomDataSetConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return (objectType == typeof(DataSet)); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     DataSet x = (DataSet)value; 
     JObject jObject = new JObject(); 
     DataTable a = x.Tables["A"]; 
     foreach (DataColumn col in a.Columns) 
     { 
      jObject.Add(col.Caption.ToLower(), a.Rows[0][col].ToString()); 
     } 
     JArray jArray = new JArray(); 
     DataTable b = x.Tables["B"]; 
     foreach (DataRow row in b.Rows) 
     { 
      JObject jo = new JObject(); 
      foreach (DataColumn col in b.Columns) 
      { 
       jo.Add(col.Caption.ToLower(), row[col].ToString()); 
      } 
      jArray.Add(jo); 
     } 
     jObject.Add("details", jArray); 
     jObject.WriteTo(writer); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

這裏是一個演示:

class Program 
{ 
    static void Main(string[] args) 
    { 
     DataSet x = new DataSet(); 
     DataTable a = x.Tables.Add("A"); 
     a.Columns.Add("Type"); 
     a.Columns.Add("Value"); 
     a.Rows.Add("A", "100"); 
     DataTable b = x.Tables.Add("B"); 
     b.Columns.Add("Name"); 
     b.Columns.Add("Age"); 
     b.Columns.Add("Gender"); 
     b.Rows.Add("John", "45", "M"); 
     b.Rows.Add("Sebastian", "34", "M"); 
     b.Rows.Add("Marc", "23", "M"); 
     b.Rows.Add("Natalia", "34", "F"); 

     JsonSerializerSettings settings = new JsonSerializerSettings(); 
     settings.Converters.Add(new CustomDataSetConverter()); 
     settings.Formatting = Formatting.Indented; 

     string json = JsonConvert.SerializeObject(x, settings); 
     Console.WriteLine(json); 
    } 
} 

輸出:

{ 
    "type": "A", 
    "value": "100", 
    "details": [ 
    { 
     "name": "John", 
     "age": "45", 
     "gender": "M" 
    }, 
    { 
     "name": "Sebastian", 
     "age": "34", 
     "gender": "M" 
    }, 
    { 
     "name": "Marc", 
     "age": "23", 
     "gender": "M" 
    }, 
    { 
     "name": "Natalia", 
     "age": "34", 
     "gender": "F" 
    } 
    ] 
} 
+0

布賴恩,非常感謝您的解決方案。這對我今天所面臨的類似問題起到了冠軍的作用。 –

2

我不認爲Json.Net會自動執行此操作,但您應該可以使用Typed Datasets執行此操作。

類型化數據集與常規DataSet/DataTable類相同,但它們使用表中每列的屬性和關係擴展它們。

編輯:

另外,您可以建立一個數據表結構轉換成一個類模型的方法,然後用Json.Net來序列化。數據模型很簡單,只有兩個類,轉換也應該很容易實現。

編輯2:

如何將數據錶轉換成類結構的一個例子:

public class ClassA 
{ 
    public string Type { get; set; } 
    public int Value { get; set; } 
    public List<ClassB> Details { get; set; } 

    public static ClassA FromDataRow(DataRow row, IEnumerable<DataRow> relatedRows) 
    { 
     var classA = new ClassA 
      { 
       Type = (string) row["Type"], 
       Value = (int) row["Value"], 
       Details = relatedRows.Select(r => new ClassB 
        { 
         Name = (string)r["Name"], 
         Age = (int)r["Age"], 
         Gender = (string)r["Gender"] 
        }).ToList() 
      }; 

     return classA; 
    } 
} 

public class ClassB 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
    public string Gender { get; set; } 
} 

在這裏,您可以運行ClassA.FromDataRow(),並從表A和一行傳遞來自TableB的行列表,並以對象結構結束。這可以很容易地序列化爲你想要的格式。

請注意,代碼必須修改以供您使用,並且可能不會按原樣編譯。但是這個概念應該清楚。

+0

dataset.Tables [0]請問我可以使用嵌套json數據的'DataTable結構到類模型'的鏈接嗎? –

+0

不,不是真的,但我可以嘗試做一個例子:-) –

1

最終解決方案供參考

using System.Web.Script.Serialization; 
public class ClassA 
{ 
    public string Type { get; set; } 
    public string Value { get; set; } 
    public List<ClassB> Details { get; set; } 

    protected void Page_Load(object sender, EventArgs e) 
    { 

     DataSet x = new DataSet(); 
     DataTable a = x.Tables.Add("A"); 
     a.Columns.Add("Type"); 
     a.Columns.Add("Value"); 
     a.Rows.Add("A", "100"); 
     DataTable b = x.Tables.Add("B"); 
     b.Columns.Add("Name"); 
     b.Columns.Add("Age"); 
     b.Columns.Add("Gender"); 
     b.Rows.Add("John", "45", "M"); 
     b.Rows.Add("Sebastian", "34", "M"); 
     b.Rows.Add("Marc", "23", "M"); 
     b.Rows.Add("Natalia", "34", "F"); 

     var s = FromDataRow(a.Rows[0], b.AsEnumerable()); 
     JavaScriptSerializer jss = new JavaScriptSerializer(); 

     string output = jss.Serialize(s); 
    } 

    public static ClassA FromDataRow(DataRow row, IEnumerable<DataRow> relatedRows) 
    { 
     var classA = new ClassA 
     { 
      Type = (string)row["Type"], 
      Value = (string)row["Value"], 
      Details = relatedRows.Select(r => new ClassB 
      { 
       Name = (string)r["Name"], 
       Age = (string)r["Age"], 
       Gender = (string)r["Gender"] 
      }).ToList() 
     }; 

     return classA; 
    } 
} 

public class ClassB 
{ 
    public string Name { get; set; } 
    public string Age { get; set; } 
    public string Gender { get; set; } 
} 
相關問題