程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 記一次項目中的查詢匯總,項目匯總

記一次項目中的查詢匯總,項目匯總

編輯:C#入門知識

記一次項目中的查詢匯總,項目匯總


  項目要實現查詢匯總的功能,針對不同的分組實現不同的匯總。直接上圖吧,直觀一點。要實現的效果如下圖所示。

 

  設計思路:第一,先實現電業局,變電工區,運維站,變電所相同的列名稱,能夠合並的功能。第二,在合適的位置插入匯總行(即有總計的行)。

  實現方法,第一,相同的列名稱合並的功能,很簡單,設置要合並的列的列屬性AllowMerge=true,並不總的GridView的AllowMerge設為true即可。

  第二,主要難點在怎麼實現匯總的功能。數據庫中的獲取的數據如下圖所示:

         PERSONID,  //人員ID              
               PERSONNAME, //人員姓名          READTICKETCOUNT, //審核步數          EXECUTETICKETCOUNT, //操作步數          LOOKUPTICKETCOUNT, //監護步數          DUTYTICKETCOUNT, //值班負責步數          TOTALTICKETCOUNT, //總計          WRITETICKETCOUNT //擬票步數

 

   既然要顯示電業局,變電工區,運維站,變電所,就要在數據表中添加對應的列,添加代碼如下:

 string[] columnNames =
            {
                DbFiledName.STATIONID.ToString() ,//電業局ID和名稱
                DbFiledName.STATION.ToString(),

                DbFiledName.YWZ.ToString(),       //變電工區ID和名稱
                DbFiledName.YWZID.ToString(),
                
                DbFiledName.BDGQ.ToString(),      //運維站ID和名稱
                DbFiledName.BDGQID.ToString(),

                DbFiledName.DYJ.ToString(),       //變電所ID和名稱
                DbFiledName.DYJID.ToString()
            };

                _commonMethod.AddColumnToDataTable(columnNames, null, ref dtTable);

  _commonMethod.AddColumnToDataTable(columnNames, null, ref dtTable)函數如下所示:

 public void AddColumnToDataTable(IEnumerable<string> columnNameList, List<string> primaryKey ,ref DataTable dtTable)
        {
            if (ReferenceEquals(columnNameList, null))
            {
                return;
            }
            foreach (var columnName in columnNameList)
            {
                DataColumn dcColumn = new DataColumn(columnName, typeof(string));    
                dtTable.Columns.Add(dcColumn);
            }

            if (ReferenceEquals(primaryKey,null)||primaryKey.Count<=0)
            {
                return;
            }

            DataColumn[] columns=new DataColumn[primaryKey.Count];
            for (int i = 0; i < primaryKey.Count; i++)
            {
                columns[i]=new DataColumn(primaryKey[i],typeof(string));
            }
            dtTable.PrimaryKey = columns;    //要設置主鍵,才能合並。
        }

  既然列已經添加就要向列中添加數據,怎麼獲取數據呢? 在構造選擇樹的時候,已經為樹中的節點傳入了必要的數據。樹的顯示圖和傳入數據為:

TreeListNode parentNode = tree.AppendNode(new object[] {
                     row["OrganizationId"], row["OrganizationName"], row["ParentId"], row["DeptClass"], row["Buro"],
                    "Organization", CheckState.Unchecked }, rootNode);

 

  既然知道了樹的節點中有需要的信息,那就遍歷樹,獲取電業局,變電工區,運維站,變電所。

foreach (var personId in personIdList) { DataRow dr = dtTable.Rows.Find(personId); //用戶 TreeListNode childNode = this.comboxOrgANdUserTree1.treeListOrganization.FindNodeByFieldValue(DbFiledName.PARENTID.ToString(), personId); if (childNode != null) { TreeListNode parentTreeListNode = childNode.ParentNode; //父節點,變電所 if (!ReferenceEquals(parentTreeListNode, null)) //3 class { string stationId = parentTreeListNode[DbFiledName.ORGANIZATIONID.ToString()].ToString(); dr[DbFiledName.STATIONID.ToString()] = stationId; dr[DbFiledName.STATION.ToString()] = parentTreeListNode[DbFiledName.ORGANIZATIONNAME.ToString()]; TreeListNode parentTreeListNodeNext = parentTreeListNode.ParentNode;//運維站 if (parentTreeListNodeNext != null) //2 class { string ywzId = parentTreeListNodeNext[DbFiledName.ORGANIZATIONID.ToString()].ToString(); dr[DbFiledName.YWZID.ToString()] = ywzId; dr[DbFiledName.YWZ.ToString()] = parentTreeListNodeNext[DbFiledName.ORGANIZATIONNAME.ToString()]; TreeListNode grandFatherTreeListNode = parentTreeListNodeNext.ParentNode; //父節點的父節點,工區 if (grandFatherTreeListNode != null) //1 class { //DbFiledName.BDGQ.ToString() string tempbdgqid = grandFatherTreeListNode[DbFiledName.ORGANIZATIONID.ToString()].ToString(); dr[DbFiledName.BDGQ.ToString()] = grandFatherTreeListNode[DbFiledName.ORGANIZATIONNAME.ToString()]; dr[DbFiledName.BDGQID.ToString()] = tempbdgqid; TreeListNode greatGrandFatherTreeListNode = grandFatherTreeListNode.ParentNode;//電業局 //父節點的父節點的父節點 if (greatGrandFatherTreeListNode != null) //0 class { string dyjid = greatGrandFatherTreeListNode[DbFiledName.ORGANIZATIONID.ToString()].ToString(); dr[DbFiledName.DYJ.ToString()] = greatGrandFatherTreeListNode[DbFiledName.ORGANIZATIONNAME.ToString()]; dr[DbFiledName.DYJID.ToString()] = dyjid; } else { dr[DbFiledName.DYJ.ToString()] = dr[DbFiledName.BDGQ.ToString()]; dr[DbFiledName.DYJID.ToString()] = dr[DbFiledName.BDGQID.ToString()]; dr[DbFiledName.BDGQ.ToString()] = dr[DbFiledName.YWZ.ToString()]; dr[DbFiledName.BDGQID.ToString()] = dr[DbFiledName.YWZID.ToString()]; dr[DbFiledName.YWZID.ToString()] = dr[DbFiledName.STATIONID.ToString()]; dr[DbFiledName.YWZ.ToString()] = dr[DbFiledName.STATION.ToString()]; } } else { dr[DbFiledName.DYJ.ToString()] = dr[DbFiledName.YWZ.ToString()]; dr[DbFiledName.DYJID.ToString()] = dr[DbFiledName.YWZID.ToString()]; dr[DbFiledName.BDGQ.ToString()] = dr[DbFiledName.STATION.ToString()]; dr[DbFiledName.BDGQID.ToString()] = dr[DbFiledName.STATIONID.ToString()]; dr[DbFiledName.YWZID.ToString()] = dr[DbFiledName.STATIONID.ToString()]; dr[DbFiledName.YWZ.ToString()] = dr[DbFiledName.STATION.ToString()]; } } else { dr[DbFiledName.YWZID.ToString()] = dr[DbFiledName.STATIONID.ToString()]; dr[DbFiledName.YWZ.ToString()] = dr[DbFiledName.STATION.ToString()]; dr[DbFiledName.BDGQ.ToString()] = dr[DbFiledName.STATION.ToString()]; dr[DbFiledName.BDGQID.ToString()] = dr[DbFiledName.STATIONID.ToString()]; dr[DbFiledName.DYJ.ToString()] = dr[DbFiledName.YWZ.ToString()]; dr[DbFiledName.DYJID.ToString()] = dr[DbFiledName.YWZID.ToString()]; //dr[DbFiledName.STATIONID.ToString()] = ""; //dr[DbFiledName.STATION.ToString()] = ""; } } } } View Code

 

  數據表的電業局,變電工區,運維站,變電所已經獲取了,接下來就要匯總數據,添加“總計”行。

                //求和之0,變電站
                stationIdList = dtTable.AsEnumerable().Select(x => x.Field<string>(DbFiledName.STATIONID.ToString())).Distinct().ToList();
                for (int i = 0; i < stationIdList.Count; i++)
                {
                    //DataRow dr = dtTable.NewRow();
                    string stationId = stationIdList[i];
                    var exprssionOne = dtTable.AsEnumerable()
                        .Where(x => x.Field<string>(DbFiledName.STATIONID.ToString()) == stationId);


                    var oneList = exprssionOne.ToList();
                    if (oneList == null || oneList.Count <= 0)
                    {
                        continue;
                    }
                    DataRow dr = dtTable.NewRow();
                    DataRow drTemp = oneList[0];

                    dr[DbFiledName.DYJID.ToString()] = drTemp[DbFiledName.DYJID.ToString()];
                    dr[DbFiledName.DYJ.ToString()] = drTemp[DbFiledName.DYJ.ToString()];
                    dr[DbFiledName.BDGQID.ToString()] = drTemp[DbFiledName.BDGQID.ToString()];
                    dr[DbFiledName.BDGQ.ToString()] = drTemp[DbFiledName.BDGQ.ToString()];

                    dr[DbFiledName.YWZID.ToString()] = drTemp[DbFiledName.YWZID.ToString()];
                    dr[DbFiledName.YWZ.ToString()] = drTemp[DbFiledName.YWZ.ToString()];//+" 總計:";

                    dr[DbFiledName.STATION.ToString()] = drTemp[DbFiledName.STATION.ToString()];
                    dr[DbFiledName.STATIONID.ToString()] = drTemp[DbFiledName.STATIONID.ToString()];

                    dr[DbFiledName.PERSONNAME.ToString()] = CountName;//CountName是“總計”

                    long m;       //PERSONID是主鍵,所以,獲取最小的主鍵並減1,作為“總計”列的主鍵,從而避免重復。
                    long newPersonId = personIdList.Where(x => long.TryParse(x, out m)).Select(x => long.Parse(x)).Min() - 1;
                    dr[DbFiledName.PERSONID.ToString()] = newPersonId.ToString();
                    personIdList.Add((newPersonId).ToString());

                    GetSumColumn(ref dtTable, ref dr, DbFiledName.STATIONID.ToString(), stationId, 1);
                    AddNewRow(ref dtTable, i, stationIdList, DbFiledName.STATIONID.ToString(), ref dr);
                }

 

   GetSumColumn和AddNewRow函數代碼:

      //獲取列的和
        private void GetSumColumn(ref DataTable dtTable, ref DataRow newRow, string id, string tempId, int div)
        {
            try
            {
                Func<List<long>, int, string> getSumFunc = (list, dicTemp) =>
              (list == null || list.Count <= 0) ? "0" : (list.Sum() / dicTemp).ToString();

                Action<DataTable, DataRow, string> resultAction = (dttable, dr, columnname) =>
                {
                    var sumColumn = dttable.AsEnumerable()
                                              .Where(x => x.Field<string>(id) == tempId)
                                              .Select(x => x.Field<long>(columnname))
                                              .ToList();

                    dr[columnname] = getSumFunc(sumColumn, div);
                };
                resultAction(dtTable, newRow, DbFiledName.READTICKETCOUNT.ToString());
                resultAction(dtTable, newRow, DbFiledName.EXECUTETICKETCOUNT.ToString());
                resultAction(dtTable, newRow, DbFiledName.LOOKUPTICKETCOUNT.ToString());
                resultAction(dtTable, newRow, DbFiledName.DUTYTICKETCOUNT.ToString());
                resultAction(dtTable, newRow, DbFiledName.DUTYTICKETCOUNT.ToString());
                resultAction(dtTable, newRow, DbFiledName.TOTALTICKETCOUNT.ToString());
                resultAction(dtTable, newRow, DbFiledName.WRITETICKETCOUNT.ToString());
            }
            catch (Exception ex)
            {
                _throwExceptionAction(ex.Message);
            }
        }

 

       //添加新行
        private void AddNewRow(ref DataTable dtTable, int i, IList<string> idList, string id, ref  DataRow dr)
        {
            try
            {
                int j = i;
                if (j < idList.Count - 1)
                {
                    var exprssionNext = dtTable.AsEnumerable()
                        .Where(x => x.Field<string>(id) == idList[j + 1]);
                    if (exprssionNext.ToList() == null || exprssionNext.ToList().Count <= 0)
                    {
                        return;
                    }
                    DataRow nextRow = exprssionNext.ToList()[0];
                    int index = dtTable.Rows.IndexOf(nextRow);
                    dtTable.Rows.InsertAt(dr, index);
                }
                else
                {
                    dtTable.Rows.Add(dr);
                }
            }
            catch (Exception ex)
            {
                _throwExceptionAction(ex.Message);
            }
        }

 

  其他的求和和電業局求和差不多,不在貼代碼了。現在所有的數據就已經有了,對數據的排列問題阻擾了我好久,最開始的時候,我是用LINQ的GroupBy來排序,結果不能顯示我要的數據。我的實現是,先對變電工區匯總,把分組完的數據分開,在對各個分開的數據中的運維站匯總,依次類推。在匯總之前,先把表中獲得數據轉化成List<T>中。轉換代碼不再給出。最後得到了需要的數據,效果如最開始的圖所示。分組代碼如下:

                //工區
                List<StepCountClass> resultClassList = new List<StepCountClass>();
                List<string> tempbdgqIdList = stepCountList.Select(x => x.BDGQID).Distinct().ToList();
                for (int i = 0; i < tempbdgqIdList.Count; i++)
                {
                    //相同變電區的組
                    var temp = stepCountList.Where(x => x.BDGQID == tempbdgqIdList[i] && x.BDGQ != CountName
                        && !string.IsNullOrEmpty(x.BDGQ)).ToList();

                    //相同運維站的組
                    var tempywzIdList = temp.Select(x => x.YWZID).Distinct().ToList();
                    for (int j = 0; j < tempywzIdList.Count; j++)
                    {
                        var ywztemp = temp.Where(x => x.YWZID == tempywzIdList[j] 
                            && x.YWZ != CountName && !string.IsNullOrEmpty(x.YWZ)).ToList();

                        //相同變電所的組
                        var stationidList = ywztemp.Select(x => x.STATIONID).Distinct().ToList();
                        for (int k = 0; k < stationidList.Count; k++)
                        {
                            var stationtemp =
                                   ywztemp.Where(x => x.STATIONID == stationidList[k]
                                       && x.STATION != CountName && !string.IsNullOrEmpty(x.STATION)).ToList();

                            //相同用戶
                            var personidList = stationtemp.Select(x => x.PERSONID).ToList();
                            for (int l = 0; l < personidList.Count; l++)
                            {
                                var persontemp =
                                    stationtemp.Where(x => x.PERSONID == personidList[l]
                                        && x.PERSONNAME != CountName && !string.IsNullOrEmpty(x.PERSONNAME))
                                        .ToList();
                                resultClassList.AddRange(persontemp);

                                if (l == personidList.Count - 1)
                                {
                                    var personCount = stationtemp.Where(x => x.PERSONNAME == CountName).ToList();
                                    resultClassList.AddRange(personCount);
                                }
                            }
                            //resultClassList.AddRange(stationtemp);
                            if (k == stationidList.Count - 1)
                            {
                                var stationCount = ywztemp.Where(x => x.STATION == CountName).ToList();
                                resultClassList.AddRange(stationCount);
                            }
                        }
                        if (j == tempywzIdList.Count - 1)
                        {
                            var ywzCount = temp.Where(x => x.YWZ == CountName).ToList();
                            resultClassList.AddRange(ywzCount);
                        }
                    }

 

  本來以為就做完了,心想萬事大吉,可是漏掉了用戶權限這一點。如果用戶的權限是電業局的話,上面正好符合要求,但是如果用戶的權限是,變電工區,那麼就查詢不到其他工區的數據,只能查到他權限內的數據。現在已運維站為例,給出解決方法。先給出樹結構圖和最後的匯總效果就明白了。

 

  從圖中可以看出僅僅顯示了,用戶所在運維站(金華操作站)中的樹結構。那麼右邊區域,也要僅僅顯示到運維站,電業局、變電工區這兩列。如下圖所示:

  this.comboxOrgANdUserTree1是一個用戶控件,RootDeptClass是根節點的級別,0代表電業局,1代表變電工區,2代表運維站,3代表變電所。

 

 switch (this.comboxOrgANdUserTree1.RootDeptClass)
                    {
                        case "0":
                            break;
                        case "1":
                            this.gridView1.Columns.ColumnByFieldName("YWZ").Visible = false;
                            var dataRowList =
                                _queryResultDt.AsEnumerable().Where(x => x.Field<string>("YWZ") == CountName).ToList();
                            foreach (var row in dataRowList)
                            {
                                _queryResultDt.Rows.Remove(row);
                            }

                            this.gridView1.Columns["DYJ"].Caption = @"變電工區";
                            this.gridView1.Columns["BDGQ"].Caption = @"運維站";
                            //_queryResultDt.Rows.RemoveAt(_queryResultDt.Rows.Count-1);
                            break;
                        case "2":
                            this.gridView1.Columns.ColumnByFieldName("YWZ").Visible = false;
                            this.gridView1.Columns.ColumnByFieldName("BDGQ").Visible = false;


                            deleteAction(DbFiledName.BDGQ.ToString());
                            deleteAction(DbFiledName.YWZ.ToString());
                            deleteAction(DbFiledName.STATION.ToString());

                         
                            List<string> personIdList = _queryResultDt.AsEnumerable().Select(x => x.Field<string>(DbFiledName.PERSONID.ToString())).ToList();
                            List<string> ywzIdList = new List<string>();
                            ywzIdList = _queryResultDt.AsEnumerable().Select(x => x.Field<string>(DbFiledName.DYJID.ToString())).Distinct().ToList();
                            for (int i = 0; i < ywzIdList.Count; i++)
                            {
                                //DataRow dr = dtTable.NewRow();
                                string ywzIdTemp = ywzIdList[i];
                                var exprssionOne = _queryResultDt.AsEnumerable()
                                    .Where(x => x.Field<string>(DbFiledName.YWZID.ToString()) == ywzIdTemp);


                                var oneList = exprssionOne.ToList();
                                if (oneList == null || oneList.Count <= 0)
                                {
                                    continue;
                                }
                                DataRow dr = _queryResultDt.NewRow();
                                DataRow drTemp = oneList[0];


                                //DataRow drTemp = exprssionOne.ToList()[0];
                                dr[DbFiledName.DYJID.ToString()] = drTemp[DbFiledName.DYJID.ToString()];
                                dr[DbFiledName.DYJ.ToString()] = drTemp[DbFiledName.DYJ.ToString()];
                                dr[DbFiledName.BDGQID.ToString()] = drTemp[DbFiledName.BDGQID.ToString()];
                                dr[DbFiledName.BDGQ.ToString()] = drTemp[DbFiledName.BDGQ.ToString()];

                                dr[DbFiledName.YWZID.ToString()] = drTemp[DbFiledName.YWZID.ToString()];
                                dr[DbFiledName.YWZ.ToString()] = drTemp[DbFiledName.YWZ.ToString()];//+" 總計:";

                                dr[DbFiledName.STATION.ToString()] = CountName;
                                long m;
                                long newPersonId = personIdList.Where(x => long.TryParse(x, out m)).Select(x => long.Parse(x)).Min() - 1;
                                dr[DbFiledName.PERSONID.ToString()] = newPersonId.ToString();
                                dr[DbFiledName.PERSONNAME.ToString()] = "";

                                personIdList.Add((newPersonId).ToString());
                                //dr[dyjName] = drTemp[dyjName];
                                GetSumColumn(ref _queryResultDt, ref dr, DbFiledName.YWZID.ToString(), ywzIdTemp, 2);
                                AddNewRow(ref _queryResultDt, i, ywzIdList, DbFiledName.YWZID.ToString(), ref dr);


                            }

                            //_queryResultDt.AsEnumerable().Where(x=>x.Field<string>("YWZ")||x.Field<string>("BDGQ"))
                            this.gridView1.Columns["DYJ"].Caption = @"運維站";
                            break;
                        case "3":
                            this.gridView1.Columns.ColumnByFieldName("DYJ").Visible = false;
                            this.gridView1.Columns.ColumnByFieldName("BDGQ").Visible = false;
                            this.gridView1.Columns.ColumnByFieldName("YWZ").Visible = false;
                            deleteAction(DbFiledName.DYJ.ToString());
                            deleteAction(DbFiledName.BDGQ.ToString());
                            deleteAction(DbFiledName.YWZ.ToString());
                            deleteAction(DbFiledName.STATION.ToString());
                            break;
                        default:
                            break;

                    }

 

this.comboxOrgANdUserTree1.RootDeptClass和 deleteAction的實現方法分別為:


       //獲取根節點等級
        public string RootDeptClass
        {
            get
            {
                for (int i = 0; i < this.treeListOrganization.AllNodesCount; i++)
                {
                    TreeListNode node = this.treeListOrganization.FindNodeByID(i);
                    if (node == null)
                        continue;
                    //DeptClass= node["DEPTCLASS"]
                    var deptClass = node["DEPTCLASS"].ToString();
                    if (string.IsNullOrEmpty(deptClass))  //所有用戶的DEPTCLASS被設置成“”
                        continue;

                    long deptClassLong;
                    //bool flag= long.TryParse(deptClass, out deptClassLong);
                    if (long.TryParse(deptClass, out deptClassLong))
                    {
                        DeptClass = deptClassLong < DeptClass ? deptClassLong : DeptClass;
                    }
                }
                return DeptClass.ToString();
            }
        }

 

 Action<string> deleteAction = fieldName =>
                    {
                        var dataRowList =
                            _queryResultDt.AsEnumerable().Where(x => x.Field<string>(fieldName) == CountName).ToList();
                        foreach (var row in dataRowList)
                        {
                            _queryResultDt.Rows.Remove(row);
                        }
                    };

 

  這樣才算完成基本,代碼還要好好重構一下,大致解決思路和主要代碼都貼出來,時間倉促,以後好好潤色。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved