将DataTable转换为JSON

joe*_*elc 0 .net c# datatable ado.net json

我在这里回顾了答案:

但它们对我的特定用例没有帮助.我正在从SQL数据适配器检索DataTable,并希望将DataTable转换为List(这很容易),然后将List序列化为JSON(使用JSON.net,这很容易).

问题是我似乎必须使用List.好的,很好 - 所以我有这个代码:

DataTable result = GoMagicallyGatherSomeData();
List<DataRow> ret = new List<DataRow>();
if (result != null && result.Rows.Count > 0)
{
  foreach (DataRow curr in result.Rows)
  {
    ret.Add(curr);
  }
}
Run Code Online (Sandbox Code Playgroud)

要么

DataTable result = GoMagicallyGatherSomeData();
List<DataRow> ret = result.AsEnumerable().ToList();
Run Code Online (Sandbox Code Playgroud)

当我去序列化List时,它......不是我所期望的.

我想回来的是:

[  
   {  
      "TestId":1,
      "AccountId":1,
      "SomeString":"This is an updated test",
      "SomeTimestamp":"2016-01-01T00:00:00Z",
      "SomeDecimal":5.55
   },
   {  
      "TestId":3,
      "AccountId":1,
      "SomeString":"This is a third test",
      "SomeTimestamp":"2016-01-01T00:00:00Z",
      "SomeDecimal":5.55
   },
   { ... removed for brevity ... }
]
Run Code Online (Sandbox Code Playgroud)

而我实际得到的是:

[  
   {  
      "RowError":"",
      "RowState":2,
      "Table":[  
         {  
            "TestId":1,
            "AccountId":1,
            "SomeString":"This is an updated test",
            "SomeTimestamp":"2016-01-01T00:00:00Z",
            "SomeDecimal":5.55
         },
         {  
            "TestId":3,
            "AccountId":1,
            "SomeString":"This is a second test",
            "SomeTimestamp":"2016-01-01T00:00:00Z",
            "SomeDecimal":5.55
         }, 
         { ... removed for brevity ... }
      ],
      "ItemArray":[  
         1,
         1,
         "This is an updated test",
         "2016-01-01T00:00:00Z",
         5.55
      ],
      "HasErrors":false
   },
   {  
      "RowError":"",
      "RowState":2,
      "Table":[  

      ... there seems to be an instance of this for every row in the result ...

      ],
      "ItemArray":[  
         1,
         1,
         "This is an updated test",
         "2016-01-01T00:00:00Z",
         5.55
      ],
      "HasErrors":false
   }
]
Run Code Online (Sandbox Code Playgroud)

另一个挑战是我需要在不了解实际数据类型的情况下这样做.

任何见解?有人建议最好的方法吗?我可以从第一个序列化的DataRow中复制掉'table'数组,或者,后续的序列化DataRows实际上是否包含与第一个不同的数据?

Fel*_*ani 5

您可以将其转换DataTable为a List<dynamic>然后将其转换为json.对于示例,要转换为动态列表:

public static List<dynamic> ConvertToDataTable(DataTable dataTable)
{
    var result = new List<dynamic>();
    foreach (DataRow row in dataTable.Rows)
    {
        dynamic dyn = new ExpandoObject();      
        foreach (DataColumn column in dataTable.Columns)
        {
            var dic = (IDictionary<string, object>)dyn;
            dic[column.ColumnName] = row[column];
        }
        result.Add(dyn);
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

您也可以像这篇文章一样制作扩展方法.然后使用它并转换为List<dynamic>最后使用JsonConvertfrom 将列表转换为json Newtonsoft.Json (a.k.a. Json.Net).样品:

var list = ConvertToDataTable(dataTable);

var json = JsonConvert.SerializeObject(list);
Run Code Online (Sandbox Code Playgroud)