2

场景如下:C# 中间层 Web 服务在 System.Data.DataTable 对象中具有从 SQL Server 发送的数据。DataTable 的列集合中有几十个列。浏览器客户端只需要查看其中大约六个。服务器上的存储过程是通用的,不是为这个特定任务设计的。假设我们必须使用它,而不是编写一个新的 SP。

是否有一种简单的方法(可能使用泛型)从该 DataTable 中提取所需的列子集到列表或集合中,然后使用 JSON.NET 将结果列表或集合转换为 JSON?

是否可以使用相关的字段名称(和数据类型)创建一个骨架 C# 类定义foo,然后“自动”匹配这些字段名称,从而List<foo>从 DataTable 的行集合中生成一个?

理想情况下,在 JSON 转换期间,任何 SQL Server 日期时间值(例如2014-06-24T18:45:00)都将被转换为一个值,该值将使在客户端中实例化 javascript Date 变得容易,而无需对日期表示进行字符串操作。

4

1 回答 1

1

完整的工作控制台应用程序代码粘贴在下面。但是您需要的两种主要方法如下。

要使此代码正常工作,您必须在项目中执行以下操作。

  1. JSON.NetNuget 包添加到项目中。
  2. 添加对System.Web.Extensions(如果System.Web.Script.Serialization.JavaScriptSerializer在方法中引用的行中出现编译错误)的引用GetJson

    /// <summary>
    /// Returns Json representation of Generic class with only matching properties from the DataTable (passed as parameter)
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="dt"></param>
    /// <returns></returns>
    public static string GetJsonFromDataTable<T>(DataTable dt) where T : new()
    {
        string json = GetJson(dt);
        return JsonConvert.SerializeObject(JsonConvert.DeserializeObject<List<T>>(json));
    }
    
    /// <summary>
    /// Returns a JSON string for entire DataTable (passed as parameter)
    /// </summary>
    /// <param name="dt"></param>
    /// <returns></returns>
    public static string GetJson(DataTable dt)
    {
        System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
        List<Dictionary<string, object>> rows = (from DataRow dr in dt.Rows select dt.Columns.Cast<DataColumn>().ToDictionary(col => col.ColumnName.Trim(), col => dr[col])).ToList();
        return serializer.Serialize(rows);
    }
    

完全工作的控制台应用程序代码。

创建一个新的控制台应用程序,并Program.cs用此代码替换其中的所有内容。还将 JSON.Net 添加到控制台应用程序项目并将引用添加到System.Web.Extensions.

namespace DataTable2Json
{
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;

    public class Patient
    {
        public string FullName { get; set; }
        public string PatientID { get; set; }
        public int NumberOfIllnesses { get; set; }
        public DateTime DateAdmitted { get; set; }
    }

    public class PatientDrug
    {
        public string Patient { get; set; }
        public string Drug { get; set; }
    }


    internal class Program
    {
        private static void Main(string[] args)
        {
            DataTable patientDrugDataTable = GetPatientDrugTable();
            DataTable patientDataTable = GetPatientTable();

            string patientDrugJson = GetJsonFromDataTable<PatientDrug>(patientDrugDataTable);
            Console.WriteLine("Json for PatientDrug:\n{0}",patientDrugJson);

            string patientJson = GetJsonFromDataTable<Patient>(patientDataTable);
            Console.WriteLine("\nJson for Patient:\n{0}", patientJson);

            Console.WriteLine("\n\nPress a key to Exit...");
            Console.ReadKey();
        }

        private static DataTable GetPatientDrugTable()
        {
        //
        // Here we create a DataTable with four columns.
        //
        DataTable table = new DataTable();
        table.Columns.Add("Dosage", typeof(int));
        table.Columns.Add("Drug", typeof(string));
        table.Columns.Add("Patient", typeof(string));
        table.Columns.Add("Date", typeof(DateTime));

        //
        // Here we add five DataRows.
        //
        table.Rows.Add(25, "Indocin", "David", DateTime.Now);
        table.Rows.Add(50, "Enebrel", "Sam", DateTime.Now);
        table.Rows.Add(10, "Hydralazine", "Christoff", DateTime.Now);
        table.Rows.Add(21, "Combivent", "Janet", DateTime.Now);
        table.Rows.Add(100, "Dilantin", "Melanie", DateTime.Now);
        return table;
        }

        private static DataTable GetPatientTable()
        {
            //
            // Here we create a DataTable with four columns.
            //
            DataTable table = new DataTable();
            table.Columns.Add("NumberOfIllnesses", typeof(int));
            table.Columns.Add("PatientID", typeof(string));
            table.Columns.Add("FullName", typeof(string));
            table.Columns.Add("DateAdmitted", typeof(DateTime));
            table.Columns.Add("StreetAddress1", typeof(string));
            table.Columns.Add("City", typeof(string));
            table.Columns.Add("State", typeof(string));
            //
            // Here we add five DataRows.
            //
            table.Rows.Add(2, "PAT-00001", "David", DateTime.Now, "1 Mill Ln", "Schenectady", "NY");
            table.Rows.Add(1, "PAT-00002", "Sam", DateTime.Now, "1915 Boylston Steet", "Boston", "MA");
            table.Rows.Add(3, "PAT-00003", "Christoff", DateTime.Now, "15 Polk Steet", "San Francisco", "CA");
            table.Rows.Add(4, "PAT-00004", "Janet", DateTime.Now, "10 Waverly St", "Los Angeles", "CA");
            table.Rows.Add(5, "PAT-00005", "Melanie", DateTime.Now, "50 Kapaa St", "Kailua", "HI");
            return table;
        }

        /// <summary>
        /// Returns Json representation of Generic class with only matching properties from the DataTable (passed as parameter)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string GetJsonFromDataTable<T>(DataTable dt) where T : new()
        {
            string json = GetJson(dt);
            return JsonConvert.SerializeObject(JsonConvert.DeserializeObject<List<T>>(json));
        }

        /// <summary>
        /// Returns a JSON string for entire DataTable (passed as parameter)
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string GetJson(DataTable dt)
        {
            System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            List<Dictionary<string, object>> rows = (from DataRow dr in dt.Rows select dt.Columns.Cast<DataColumn>().ToDictionary(col => col.ColumnName.Trim(), col => dr[col])).ToList();
            return serializer.Serialize(rows);
        }
    }
}

代码说明:

请注意,我有 2 个课程,Patient并且PatientDrug. 我编写了帮助方法来返回两个类的数据表,它们都有额外的列。然后以下 2 行分别获取 和 的类表示的 JSON PatientPatientDrug同时忽略 DataTable 中与名称不匹配的其他数据列。

string patientDrugJson = GetJsonFromDataTable<PatientDrug>(patientDrugDataTable);
string patientJson = GetJsonFromDataTable<Patient>(patientDataTable);

控制台窗口中的输出(json 字符串)

在此处输入图像描述

于 2014-06-26T00:01:49.677 回答