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();

*/

}

原文地址:https://www.cnblogs.com/zrprj/p/9495856.html

时间: 2024-10-27 10:58:52

linq中分组查询而且获取每个分组中的第一条记录,数据用于分页绑定的相关文章

mybatis 关联查询时,从表只返回第一条记录解决办法

如果两表联查,主表和明细表的主键都是id的话,明细表的多条只能查询出来第一条. 造成以上情况可能的原因: 1.级联查询的时候,主表和从表有一样的字段名的时候,在mysql上命令查询是没问题的.但在mybatis中主从表需要为相同字段名设置别名.设置了别名就OK了. 例子: 主表Standard, 从表StandEntity,均有名为id的字段 1 <resultMap id="StandardAndEntityResultMap" type="whu.edu.irlab

SQL 查询每组的第一条记录

CREATE TABLE [dbo].[test1]( [program_id] [int] NULL, [person_id] [int] NULL ) ON [PRIMARY] /*查询每组分组中第一条记录*/ select * from test1 as a where a.person_id in ( select top 1 person_id from test1 where program_id = a.program_id); select * from ( select ROW

Oracle取查询结果数据的第一条记录SQL

Oracle取查询结果数据的第一条记录SQL: select * from (select * from <table> order by <key>) where rownum=1; select * from (select * from <table> order by <key> desc) where rownum=1;

sql中筛选第一条记录【分组排序】

问题描述 我们现在有一张表titles,共有4个字段,分别是emp_no(员工编号),title(职位),from_date(起始时间),to_date(结束时间),记录的是员工在某个时间段内职位名称,因为会存在升职,转岗之类的,里面emp_no可能会对应多个职位,我们现在要取到所有员工最近的职位信息,包括离职员工. 本文介绍两种方法去实现结果: 方法一 嵌套一个group by+max()子查询获取最近的职位信息. 思路 通过对emp_no分组取每个emp_no对应的最大的from_date:

Android开发中根据图片名称获取在drawable中的ID

在Android开发中图片资源是必不可少的,如ImageView需要图片资源的ID,ImageButton需要资源的ID等等,我们可以用R.drawable.XXX可以获取图片资源的ID,但是,在某些时候,这样做很费时,我们想动态的获得资源ID,比如说,我传入一个图片名称的字符串,根据字符串来获得资源的ID这样就很方便了,没错,这样确实很方便,我们如果对图片的名称稍加改动,比如用img1.png,img2.png,img3.png...这样就可以在一个循环之内获得所有的ID,对开发来说少写的就不

Oracle查询出最最近一次的一条记录

需求:从一个表中查询数据,得到的数据为最新的一条记录. -------------建立测试表 --drop table TB CREATE TABLE TB(ID INT,Name VARCHAR(100),dtDate date) -------------插入测试数据 insert into TB VALUES(1,'杰克',to_date('2015/10/12','YYYY/MM/DD')); insert into TB VALUES(2,'琼斯',to_date('2016/01/1

取得left join的第二表中符合条件的第一条记录

问题描述 有表一 tableA tid     username     title 1         lily       我公司将进行xx培训 2        angus      关于秋游的通知 3        boss       这个月不发奖金 4        vivi       新产品上市 表二 tableB tid      time     txt 1        0809    大家快来.... 2        0810    我是新来的,大家好 2       

sql分组获取第一条记录(sql+oracle)

sql版本 select * from (select t.CloseDate,t.ExpiryDate,t.DataTypeLookupID,ROW_NUMBER() over(partition by CloseDate,ExpiryDate,DataTypeLookupID order by CloseDate,ExpiryDate,DataTypeLookupID) as new_index from dbo.IndexVolatilityMarketData t ) a where a

将数据保存在web.config配置文件中,及如何获取config配置文件中的数据

<1> 有的数据需要写到配置文件中的.我们就尽量写到配置文件中来.比如经常变动的数据 ,或者用户时候的时候只要改改配置文件就可以了用了的值,如:ip地址.端口号,MD5加盐.等等.我们可以将这些值写入到web.config文件中来.在webForm.aspx.cs页面,或者其他页面去获取这个值就可以了 注意是在<appSettings></appSettings>文件中进行配置. <?xml version="1.0" encoding=&qu