【问题标题】:Format JSON Object from DataTable从 DataTable 格式化 JSON 对象
【发布时间】:2017-09-21 16:28:38
【问题描述】:

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

这是我运行存储过程的 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)...

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

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

【问题讨论】:

  • 你能定义'ColumnName'吗?
  • "ColumnName" 是从存储过程返回的列的名称。不幸的是,它的值是动态的,所以它们可以是任何东西。
  • 如果您不想要“ColumnName”,为什么要从程序中返回它?我错过了什么吗?

标签: c# json tsql sqldataadapter


【解决方案1】:

您必须转换为如下列表:

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)

应该可以的。

【讨论】:

  • 应该dataTable.ToList();读取数据表.ToList();
  • 不,您必须创建一个具有我将更新 anwser 的属性的类
  • SQL 返回动态结果,因此在运行之前我不会知道列。因此 Table 类将不起作用。
【解决方案2】:

这段代码对我有用。我使用 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;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-16
    • 2019-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-11
    相关资源
    最近更新 更多