• 每日学习总结:根据给定的时间段,返回时间段内的月(年/季度)的数组、使用JavascriptSerializer类将DataTable序列化和反序列化


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

    示例: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;
            }
    

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

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

    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;
            }
    

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

  • 相关阅读:
    14.18 InnoDB Backup and Recovery 备份和恢复:
    14.18 InnoDB Backup and Recovery 备份和恢复:
    php使用 _before_index() 来实现访问页面前,判断登录
    php使用 _before_index() 来实现访问页面前,判断登录
    查询方式实例演示
    查询方式实例演示
    haproxy timeout server 46000 后台超时时间
    haproxy timeout server 46000 后台超时时间
    14.10.5 Reclaiming Disk Space with TRUNCATE TABLE 回收空间使用TRUNCATE TABLE
    14.10.5 Reclaiming Disk Space with TRUNCATE TABLE 回收空间使用TRUNCATE TABLE
  • 原文地址:https://www.cnblogs.com/Olive116/p/2998923.html
Copyright © 2020-2023  润新知