2014-02-12 113 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; } 
} 
相关问题