从DataTable格式化JSON对象

时间:2017-09-21 16:28:39

标签: c# json tsql sqldataadapter

我有一个SQL存储过程,它返回2个动态结果集 - 数据(在JSON中命名为“Table”)和一组列(Table1)。

这是我运行sproc的C#代码......

using (SqlConnection sqlcon = new SqlConnection(ConfigurationManager.ConnectionStrings["TESTCONN"].ConnectionString))
{
    using (SqlCommand cmd = new SqlCommand("[Model].[TaskRecord_GetAll]", sqlcon))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("@Period", period);

        using (SqlDataAdapter da = new SqlDataAdapter(cmd))
        {
            DataSet ds = new DataSet();
            DataTable dt1 = new DataTable();
            DataTable dt2 = new DataTable();

            da.Fill(ds);
            dt1 = ds.Tables[0];
            dt2 = ds.Tables[1];

            string json = JsonConvert.SerializeObject(ds, Formatting.Indented);
            return json;
        }
    }
}

这是我上面代码中的当前JSON对象......

{
  "Table": [
    {
      "Entity": "TEST",
      "Period": "2017-08-31T00:00:00",
      "Level": "5",
      "Errors": "Approved",
      "Process": "OK",
      "Corporate": "Created"
    }
  ],
  "Table1": [
    {
      "ColumnName": "Entity"
    },
    {
      "ColumnName": "Period"
    },
    {
      "ColumnName": "Level"
    },
    {
      "ColumnName": "Errors"
    },
    {
      "ColumnName": "Process"
    },
    {
      "ColumnName": "Corporate"
    }
  ]
}

但是,我需要这种格式的JSON对象:

{
  "Table": [
    {
      "Entity": "TEST",
      "Period": "2017-08-31T00:00:00",
      "Level": "5",
      "Errors": "Approved",
      "Process": "OK",
      "Corporate": "Created"
    }
  ],
  "Table1": [
    {
      "Entity",
      "Period",
      "Level",
      "Errors",
      "Process",
      "Corporate"
    }
  ]
}

我的第二个SQL结果集(提供给Table1)......

enter image description here

我需要在DataTable代码中更新什么才能确保返回所需的JSON对象?我是否必须更改SQL sproc返回数据的方式?

我不能使用LINQ / EF,因为列是动态的,并且可以从sproc中返回任何数字。

2 个答案:

答案 0 :(得分:0)

您必须转换为以下列表:

public static class DataTableToList
{
    public static List<T> ToList<T>(this DataTable dataTable)
        where T:class,new()
    {
        var list = new List<T>();
        var typeOfT = typeof(T);
        foreach (DataRow row in dataTable.Rows)
        {
            var t = new T();
            foreach (DataColumn column in dataTable.Columns)
            {
                var propertyName = column.ColumnName;                    
                var property = t.GetType().GetProperty(propertyName);
                if (property != null)
                {
                    property.SetValue(t, Convert.ChangeType(row[column],property.PropertyType,null));
                }
            }
            list.Add(t);
        }
        return list;
    }
}

使用:

    public class Table
    {
        public string Entity { get; set; }
        public int Period { get; set; }
        public string Level { get; set; }
        public string Process { get; set; }
        public string Corporate { get; set; }
    }

var list = dataTable.ToList<Table>();
var jsonString = JsonConvert.SerializeObject(list)

应该这样做。

答案 1 :(得分:0)

这段代码对我有用。我使用NewtonSoft JSON来组合两个JSON对象......

using (SqlConnection sqlcon = new SqlConnection(ConfigurationManager.ConnectionStrings["TESTCONN"].ConnectionString))
{
    using (SqlCommand cmd = new SqlCommand("[Model].[TaskRecord_GetAll]", sqlcon))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("@Period", period);

        using (SqlDataAdapter da = new SqlDataAdapter(cmd))
        {
            DataSet ds = new DataSet();
            DataTable dt1 = new DataTable();
            DataTable dt2 = new DataTable();

            da.Fill(ds);
            dt1 = ds.Tables[0];
            dt2 = ds.Tables[1];

            List<DataRow> list = dt2.AsEnumerable().ToList();

            List<string> colList = new List<string>();
            foreach(DataRow row in list)
            {
                colList.Add(row.ItemArray[0].ToString());
            }

            var jsonString = JsonConvert.SerializeObject(new
            {
                columns = colList
            }, Formatting.Indented);

            ds.Tables.Remove(dt2);

            string json = JsonConvert.SerializeObject(ds, Formatting.Indented);

            JObject o1 = JObject.Parse(jsonString);
            JObject o2 = JObject.Parse(json);

            o1.Merge(o2, new JsonMergeSettings
            {
                // union array values together to avoid duplicates
                MergeArrayHandling = MergeArrayHandling.Union
            });
            string jsonResult = o1.ToString();

            return jsonResult;
        }
    }
}