zoukankan      html  css  js  c++  java
  • 将Datatable序列化为Json对象返回到客户端

    1、根据给定的时间段,返回时间段内的月(年/季度)的数组
    解析:
        这是上周项目中遇到的一个问题,在sql中通过DatePart()函数,加上group by 分组来实现,获取给定时间段内每月(/年、季度)的相关信息,
        但是这样有一个问题,如果数据库里边在符合条件的时间段内没有相关信息的话,返回的信息是不完整的,
        示例:返回2012年1月1日,到2012年12月31日范围区间的数据,按月分组,正常情况下该出现12个月的信息,但是如果某个月没有信息,则可能
        返回的信息少于12条,但是项目要求,应该返回完整的信息,如果没有值的话,默认为0。刚开始的时候毫无头绪,有想过用List来暂时存储信息,
        然后最后再做统一处理,但是这样会带来一些不必要的开销。后来想了到这样的方法,主要思想是分段处理,分三段:开始那一年、中间完整的那几年
        、最后那一年,这样就把问题给细化,简单了许多。具体请看下面代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    <span style="font-size: 15px;">示例:startDate:20060116 ,endDate:20121115,type参数:yy(年),mm(月),qq(季度)
            /// <summary>
            /// 获取不同日期类型对应的日期数组,yy为年,qq为季度,mm为月
            /// </summary>
            /// <param name="chart"></param>
            /// <returns></returns>
    public string[] GetDateCount(string startDate,string endDate,string type)
            {
                int startYear = Convert.ToInt32(startDate.Substring(0, 4));//开始的那一年
                int endYear = Convert.ToInt32(endDate.Substring(0, 4));//结束的那一年
                int startMonth, endMonth;//开始/结束的那一月
                int yearCount = endYear - startYear + 1;//开始与结束年之差
                string[] dates = new string[0];
                switch (type)
                {
                    case "yy"://返回的时间粒度为年
                        dates = new string[yearCount];
                        for (int i = 0; i < yearCount; i++)
                        {
                            dates[i] = startYear.ToString();
                            startYear++;
                        }
                        break;
                    case "qq"://返回的时间粒度为季度
                        yearCount = endYear - startYear - 1;//返回完整的年的个数,开始那一年,和结束那一年除外
                        startMonth = Convert.ToInt32(startTime.Substring(4, 2));//获取开始的那一年的月份
                        endMonth = Convert.ToInt32(endTime.Substring(4, 2));//获取结束那一年的月份
                        int qsm, qem, qsml, qeml;
                        qsm = GetIntQ(startMonth);//调用GetInQuiry函数,获取开始时间为当年的第几季度
                        qem = GetIntQ(endMonth);//调用GetInQuiry函数,获取结束时间为当年的第几季度
                        qsml = 4 - qsm;//获取开始那一年有多个季度在统计范围内
                        qeml = qsm;//获取结束那一年有多少个季度在统计范围内
                        dates = new string[qsml + yearCount * 4 + qeml];//初始化返回的数组,数组大小即为给定范围内的季度
                        for (int i = 0; i < qsml; i++)//初始化数组,开始那一年的季度
                        {
                            dates[i] = startYear.ToString() + qsm.ToString();
                            qsm++;
                        }
                        for (int y = 1; y <= yearCount; y++)//完整的那几年的季度
                        {
                            int j = 1;
                            int qsi = qsml + (y - 1) * 4;
                            for (int i = qsi; i < y * 4 + qsml; i++)
                            {
                                dates[i] = (startYear + y).ToString() + j.ToString();
                                j++;
                            }
                        }
                        int qeb = 1;
                        for (int k = (qsml + yearCount * 4); k < qsml + yearCount * 4 + qeml; k++)//结束那一年的季度
                        {
                            dates[k] = endYear.ToString() + qeb.ToString();
                            qeb++;
                        }
                        break;
                    case "mm":
                        startMonth = Convert.ToInt32(startTime.Substring(4, 2));
                        endMonth = Convert.ToInt32(endTime.Substring(4, 2));
                        int sm = 12 - startMonth + 1;//起始那一年总共的月份
                        int em = endMonth;//截止那一年总共的月份
                        yearCount = endYear - startYear - 1;//间隔时间段内完整的年数
                        dates = new string[sm + yearCount * 12 + em];//总共有多个月要统计
                        for (int i = 0; i < sm; i++)//起始那一年的月份
                        {
                            dates[i] = startYear.ToString() + startMonth.ToString();
                            startMonth++;
                        }
                        for (int y = 1; y <= yearCount; y++)
                        {
                            int j = 1;
                            int si = sm + (y - 1) * 12;
                            for (int i = si; i < y * 12 + sm; i++)
                            {
                                dates[i] = (startYear + y).ToString() + j.ToString();
                                j++;
                            }
                        }
                        int eb = 1;
                        for (int k = (sm + yearCount * 12); k < sm + yearCount * 12 + em; k++)
                        {
                            dates[k] = endYear.ToString() + eb.ToString();
                            eb++;
                        }
                        break;
                    default:
                        dates = new string[0];
                        break;
                }
                return dates;
            }
              /// <summary>
            /// 用来获取当前月对应的季度
            /// </summary>
            /// <param name="i"></param>
            /// <returns></returns>
            public static int GetIntQ(int i)
            {
                int r = 0;
                if (i <= 3)
                {
                    r = 1;
                }
                else if (3 < i && i <= 6)
                {
                    r = 2;
                }
                else if (6 < i && i <= 9)
                {
                    r = 3;
                }
                else if (9 < i && i <= 12)
                {
                    r = 4;
                }
                return r;
            }
    </span>

      2、使用JavascriptSerializer类将DataTable序列化和反序列化

    解析:
         JavascriptSerializer类一般多用来将一个List<ClassName>对象序列化,关于这一点我在Serialization全解析一文中有提到,
         有不太懂的朋友可以看一下了解了解。虽是这样,JavascriptSerializer类没有专门的序列话DataTable的方法,非官方的有
         Nowtonsoft.Json是一个做的很不错的第三放的dll,也可以直接拿来用,但是今天要讲的是用JavascriptSerializer来实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    <span style="font-size: 14px;">DataTable的序列化和反序列化
            /// <summary>DataTable序列化
            /// </summary>
            /// <param name="dt"></param>
            /// <returns></returns>
            public string SerializeDataTable(DataTable dt)
            {
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
                foreach (DataRow dr in dt.Rows)//每一行信息,新建一个Dictionary<string,object>,将该行的每列信息加入到字典
                {
                    Dictionary<string, object> result = new Dictionary<string, object>();
                    foreach (DataColumn dc in dt.Columns)
                    {
                        result.Add(dc.ColumnName, dr[dc].ToString());
                    }
                    list.Add(result);
                }
                return serializer.Serialize(list);//调用Serializer方法
            }
            /// <summary>DataTable反序列化
            /// </summary>
            /// <param name="strJson"></param>
            /// <returns></returns>
     public DataTable DeserializerTable(string strJson)
            {
                DataTable dt = new DataTable();
                        JavaScriptSerializer serializer = new JavaScriptSerializer();
                       // var obj = serializer.DeserializeObject(strJson);//反序列化
                        ArrayList arralList = serializer.Deserialize<ArrayList>(aaa);//反序列化ArrayList类型
                        if (arralList.Count > 0)//反序列化后ArrayList个数不为0
                        {
                            foreach (Dictionary<string, object> row in arralList)
                            {
                                if (dt.Columns.Count == 0)//新建的DataTable中无任何信息,为其添加列名及类型
                                {
                                    foreach (string key in row.Keys)
                                    {
                                        dt.Columns.Add(key, row[key].GetType());//添加dt的列名
                                    }
                                }
                                DataRow dr = dt.NewRow();
                                foreach (string key in row.Keys)//讲arrayList中的值添加到DataTable中
                                {
     
                                    dr[key] = row[key];//添加列值
                                }
                                dt.Rows.Add(dr);//添加一行
                            }
                        }
                    }
                return dt;
            }
    </span>

      上边总结 的这些都是在项目中遇到的问题,然后有了些思路,写成了一些具体的方法,希望能给朋友们一些帮助。

  • 相关阅读:
    区块链入门
    上海美食餐厅
    《OD学hadoop》20160910某旅游网项目实战
    《OD学hadoop》20160904某旅游网项目实战
    《OD学hadoop》20160903某旅游网项目实战
    qt5-自定义类
    qt5-Qt Creator使用
    qt5-QPushButton按钮
    qt5-工程文件的介绍--快捷键
    电路分析-电阻
  • 原文地址:https://www.cnblogs.com/anbylau2130/p/3134020.html
Copyright © 2011-2022 走看看