linq中分組查詢而且獲取每個分組中的第一條記錄,數據用於分頁綁定


LINQ分組取出第一條數據

Person1: Id=1, Name="Test1"

Person2: Id=1, Name="Test1"

Person3: Id=2, Name="Test2"

以上list如果直接使用distinct方法進行過濾,仍然返回3條數據,而需要的結果是2條數據。下面給出解這個問題的方法:

方法1: Distinct 方法中使用的相等比較器。這個比較器需要重寫Equals和GetHashCode方法,個人不推薦,感覺較麻煩,需要些多余的類,並且用起來還要實例化一個比較器,當然自己也可以寫一個泛型的比較器生成工廠用來專門生成比較器,但仍然覺得較麻煩。

              MSDN給出的做法,具體參照:http://msdn.microsoft.com/zh-cn/library/bb338049.aspx

方法2:自己擴展一個DistinctBy。這個擴展方法還是很不錯的,用起來很簡潔,適合為框架添加的Distinct擴展方法。

 

public static IEnumerable<TSource> DistinctBy<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)

{

    HashSet<TKey> seenKeys = new HashSet<TKey>();

    foreach (TSource element in source)

    {

        if (seenKeys.Add(keySelector(element)))

        {

            yield return element;

        }

    }

}

 

使用方法如下(針對ID,和Name進行Distinct):

var query = people.DistinctBy(p => new { p.Id, p.Name });

若僅僅針對ID進行distinct:

var query = people.DistinctBy(p => p.Id);

方法3:通過GroupBy分組后,並取出第一條數據。簡單易用,很方便。這是一種迂回策略,代碼理解起來沒有Distinct表意清晰,雖然實現了效果。

 

List<Person> distinctPeople = allPeople

  .GroupBy(p => new {p.Id, p.Name} )

  .Select(g => g.First())

  .ToList();

//這個看起來很美好,但是綁定到gridview時則不顯示也不提示錯誤,采用下面的方法很可靠

ViewState["0964zt"] = "簡易報警"; //不顯示暫停

        bool xswg = this.chk_xswg.Checked;//是否顯示完工

        if (xswg)//顯示所有延期的記錄,按照ddid降序排列的1000條記錄

        {

           

           

            var cx_dd_bj = (from aa in sjklj.sc_ddxx

                  where aa.yq.HasValue && aa.yq.Value > 0 && ((aa.zt.HasValue && aa.zt == false) || aa.zt.HasValue == false)

                  orderby aa.ddid descending

                  select aa).Take(1000).GroupBy(bb => bb.ddid);

            List<sc_ddxx> lst_jybq = new List<sc_ddxx>();

            lst_jybq.Clear();

            foreach(var kk in cx_dd_bj)

            {

                foreach(var gg in kk)

                {

                    lst_jybq.Add(gg);//獲取了第一條記錄

                    break;

                }

            }

           

           

            this.gv_scjh.DataSource = lst_jybq;

            try

            {

                this.gv_scjh.PageIndex = 0;

            }

            catch(Exception err)

            {

                aspnetajaxjavascript.Msg(this.UpdatePanel1, err.Message, "2", "3000");

            }

            this.gv_scjh.DataBind();

           

        }

        else //不顯示完工的,即沒有完工的,就是【待定】

        {

 

 

            var cx_dd_bj = (from aa in sjklj.sc_ddxx

                            where aa.czzt == "待定" && aa.yq.HasValue && aa.yq.Value > 0 && ((aa.zt.HasValue && aa.zt == false) || aa.zt.HasValue == false)

                            orderby aa.ddid descending

                            select aa).Take(1000).GroupBy(bb => bb.ddid);

            List<sc_ddxx> lst_jybq = new List<sc_ddxx>();

            lst_jybq.Clear();

            foreach (var kk in cx_dd_bj)

            {

                foreach (var gg in kk)

                {

                    lst_jybq.Add(gg);//獲取了第一條記錄

                    break;

                }

            }

           

            this.gv_scjh.DataSource = lst_jybq;

            try

            {

                this.gv_scjh.PageIndex = 0;

            }

            catch (Exception err)

            {

                aspnetajaxjavascript.Msg(this.UpdatePanel1, err.Message, "2", "3000");

            }

            this.gv_scjh.DataBind();

           

        }

Linq分組及排序,取前N條記錄

2016年05月18日 15:02:10

閱讀數:5199

Linq多字段分組排序並取前N條記錄時,一定要先分組再排序,不然取到的記錄是不規則的

代碼示例【按HotWord分組,並取sorNum倒序,取前15條記錄】

  1.         [Route("api/XXX/getHotWord")]
  2.         public HttpResponseMessage Post(WordModel model)
  3.         {
  4.             try
  5.             {   
  6.                 using (BZTEntities ctx = new BZTEntities())
  7.                 {                  
  8.                     var wflist = from u in ctx.T_HotWord
  9.                                  where u.Type==model.type                               
  10.                                  group u by new { HotWord = u.HotWord, sortNum = u.SortNum } into g                               
  11.                                  select new { g.Key.HotWord, g.Key.sortNum };
  12.                     wflist = wflist.OrderByDescending(x => x.sortNum);
  13.                     var hotWord = wflist.ToList().Take(15).Select(a => a.HotWord).ToList();
  14.                     var Str = string.Join(",", hotWord);
  15.                     return Request.CreateResponse(HttpStatusCode.OK, new { errorCode = 1, hotWord = Str });
  16.                 }
  17.             }
  18.             catch (Exception ex)
  19.             {
  20.                 Log.Error("獲取xxxxx失敗:" + ex.Message, ex);
  21.                 return Request.CreateResponse(HttpStatusCode.OK, new { errorCode = 2 });
  22.             }
  23.         }
  24.     }

特別提醒:list對象綁定gridview時,如果用自帶的分頁事件綁定,則不能實現分頁,下面的代碼完美解決。

bool xswg = this.chk_xswg.Checked;//是否顯示完工

        if (xswg)//顯示所有延期的記錄,按照ddid降序排列的1000條記錄

        {

 

           

            var cx_dd_bj = (from aa in sjklj.sc_ddxx

                            where aa.yq.HasValue && aa.yq.Value > 0 && ((aa.zt.HasValue && aa.zt == false) || aa.zt.HasValue == false)

                           orderby aa.ddid descending

                           select aa).Take(1000).GroupBy(bb => bb.ddid).OrderByDescending(cc => cc.Key)

                           .Select(dd => dd.FirstOrDefault());

            this.gv_scjh.DataSource = cx_dd_bj;

            this.gv_scjh.DataBind();

     // FirstOrDefault()是解決意外錯誤的好方法,否則可能沒有數據顯示甚至沒有提示

            /*

            List<sc_ddxx> lst_jybq = new List<sc_ddxx>();

            lst_jybq.Clear();

            foreach(var kk in cx_dd_bj)

            {

                foreach(var gg in kk)

                {

                    lst_jybq.Add(gg);//獲取了第一條記錄

                    break;

                }

            }

 

            //用戶viewstate["datajybj"]記錄list數據

            ViewState["datajybj"] = lst_jybq;

           

            this.gv_scjh.DataSource = lst_jybq;

            try

            {

                this.gv_scjh.PageIndex = 0;

            }

            catch(Exception err)

            {

                aspnetajaxjavascript.Msg(this.UpdatePanel1, err.Message, "2", "3000");

            }

            this.gv_scjh.DataBind();

            */

 

        }

        else //不顯示完工的,即沒有完工的,就是【待定】

        {

 

 

            var cx_dd_bj = (from aa in sjklj.sc_ddxx

                            where aa.czzt == "待定" && aa.yq.HasValue && aa.yq.Value > 0 && ((aa.zt.HasValue && aa.zt == false) || aa.zt.HasValue == false)

                            orderby aa.ddid descending

                            select aa).Take(1000).GroupBy(bb => bb.ddid).OrderByDescending(cc => cc.Key)

                            .Select(dd => dd.FirstOrDefault());

            this.gv_scjh.DataSource = cx_dd_bj;

            this.gv_scjh.DataBind();

            return;

            /*

            List<sc_ddxx> lst_jybq = new List<sc_ddxx>();

            lst_jybq.Clear();

            foreach (var kk in cx_dd_bj)

            {

                foreach (var gg in kk)

                {

                    lst_jybq.Add(gg);//獲取了第一條記錄

                    break;

                }

            }

 

            //用戶viewstate["datajybj"]記錄list數據

            ViewState["datajybj"] = lst_jybq;

            this.gv_scjh.DataSource = lst_jybq;

            try

            {

                this.gv_scjh.PageIndex = 0;

            }

            catch (Exception err)

            {

                aspnetajaxjavascript.Msg(this.UpdatePanel1, err.Message, "2", "3000");

            }

            this.gv_scjh.DataBind();

            */

           

        }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM