[英]Looking for a more elegant LINQ solution
I am trying to figure out an efficient way to retrieve the data I am after. 我试图找出一种有效的方法来检索我想要的数据。 I need to get a list of all of the most recent children by ParentId coupled with all parent entries that do NOT have children.
我需要通过ParentId获取所有最近子项的列表,以及所有没有子项的父项。 I have created a visual guide to illustrate what the response should be.
我创建了一个直观的指南来说明应采取的措施。
The query needs to remain as IQueryable until ALL sorting and paging is completed. 在所有排序和分页完成之前,查询需要保持为IQueryable。
Last
and LastOrDefault
are not supported by LINQ to Entities (as stated by the error messages I have received while using them). LINQ to Entities不支持
Last
和LastOrDefault
(如我在使用它们时收到的错误消息所述)。
Using First
or FirstOrDefault
will return the error " This method or operation is not implemented
" 使用
First
或FirstOrDefault
将返回错误“ This method or operation is not implemented
”
Original Data: 原始数据:
-------------------------------
- Id - ParentId - CreatedDate -
-------------------------------
- 1 - - 07/01/2013 -
- 2 - - 07/01/2013 -
- 3 - - 07/01/2013 -
- 4 - 1 - 07/02/2013 -
- 5 - 2 - 07/03/2013 -
- 6 - 2 - 07/04/2013 -
- 7 - 1 - 07/05/2013 -
-------------------------------
Data returned by query 查询返回的数据
-------------------------------
- Id - ParentId - CreatedDate -
-------------------------------
- 3 - - 07/01/2013 -
- 6 - 2 - 07/04/2013 -
- 7 - 1 - 07/05/2013 -
-------------------------------
Currently, my LINQ query looks like this: 目前,我的LINQ查询看起来像这样:
// Retrieves parent records with NO children.
var q1 = myTable
.Where(x => x.ParentId == null)
.Except(myTable
.Where(x => myTable
.Any(c => (c.ParentId == x.Id))));
// Retrieves most recent child records for each parentId
var q2 =
(from a in myTable
join b in
(myTable.Where(a => a.ParentId != null)
.GroupBy(a => a.ParentId)
.Select(b => new { ParentId = b.Key, CreatedDate = b.Max(t => t.CreatedDate) }))
on a.ParentId equals b.ParentId
where a.CreatedDate == b.CreatedDate
select a);
q1 = q1.Union(q2);
The back-end is using Npgsql2 with PostgreSQL. 后端将Npgsql2与PostgreSQL一起使用。 I am looking for a more elegant solution for this query.
我正在为此查询寻找更优雅的解决方案。 I am very new to LINQ and would like to optimize this.
我对LINQ非常陌生,想对此进行优化。
Sorting code (sloppy, but jTable returns these strings): 排序代码(草率,但jTable返回这些字符串):
if (string.IsNullOrEmpty(sorting) || sorting.Equals("Name ASC")) {
q1 = q1.OrderBy(p => p.Customer.Name);
} else if (sorting.Equals("Name DESC")) {
q1 = q1.OrderByDescending(p => p.Customer.Name);
} else if (sorting.Equals("Date ASC")) {
q1 = q1.OrderBy(p => p.CreatedDate);
} else if (sorting.Equals("Date DESC")) {
q1 = q1.OrderByDescending(p => p.CreatedDate);
}
Paging code: 分页代码:
var result = pageSize > 0
? q1.Skip(startIndex).Take(pageSize).ToList()
: q1.ToList();
Use grouping: 使用分组:
Mock data: 模拟数据:
public class Entry {
public int Id { get; set; }
public int? ParentId { get; set; }
public DateTime Date { get; set; }
};
var list = new List<Entry> {
new Entry{ Id = 1, ParentId = null, Date = new DateTime(2013, 7, 1) },
new Entry{ Id = 2, ParentId = null, Date = new DateTime(2013, 7, 1) },
new Entry{ Id = 3, ParentId = null, Date = new DateTime(2013, 7, 1) },
new Entry{ Id = 4, ParentId = 1, Date = new DateTime(2013, 7, 2) },
new Entry{ Id = 5, ParentId = 2, Date = new DateTime(2013, 7, 3) },
new Entry{ Id = 6, ParentId = 2, Date = new DateTime(2013, 7, 4) },
new Entry{ Id = 7, ParentId = 1, Date = new DateTime(2013, 7, 5) }
};
Query: 查询:
var query = from l in list
group l by l.ParentId into g
select new {
Items = g.OrderBy(x => x.Date).Last()
};
var res = query.OrderBy(x => x.Items.Id).Select(x => x.Items).ToList();
LinqPad result: LinqPad结果:
Id ParentId Date
3 null 01.07.2013 0:00:00
6 2 04.07.2013 0:00:00
7 1 05.07.2013 0:00:00
I can propose a different query, still in two phases 我可以提出一个不同的查询,仍然分两个阶段
var firstQuery = myTable.Select(p => new { p.ID, ParentID = p.ParentID ?? p.ID, p.CreatedDate })
.GroupBy( p => p.ParentID).Select( q => new
{
el = q.OrderByDescending( k => k.CreatedDate).Take(1)
}).SelectMany(t => t.el);
var result = dc.TabellaId_ParentId.Where(p => test.Select(q => q.ID).Contains(p.ID));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.