简体   繁体   English

寻找更优雅的LINQ解决方案

[英]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不支持LastLastOrDefault (如我在使用它们时收到的错误消息所述)。

Using First or FirstOrDefault will return the error " This method or operation is not implemented " 使用FirstFirstOrDefault将返回错误“ 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.

相关问题 寻找更优雅的DO WHILE解决方案 - Looking for a more elegant DO WHILE solution Entity Framework Core + Linq:如何获得具有最大值的整个实体? 寻找更优雅的解决方案 - Entity Framwork Core + Linq: How do I get the entire entity that has the max value? Looking for a more elegant solution SomeButNotAll()有一个优雅的LINQ解决方案吗? - Is there an elegant LINQ solution for SomeButNotAll()? 寻找一个优雅的LINQ查询,替代SelectMany - Looking for an elegant LINQ query, alternative to SelectMany 将switch语句转换为更优雅的解决方案 - Converting switch statements to more elegant solution WPF文本框和浏览文件 - 有更优雅的解决方案吗? - WPF textbox and browse file - is there a more elegant solution? 更优雅的LINQ替代Foreach扩展 - More Elegant LINQ Alternative to Foreach Extension 如何使此LINQ to XML查询更优雅? - How to make this LINQ to XML query more elegant? 寻找用于整数键模型的优雅/有效的解决方案 - Looking for elegant / efficient solution for integer keyed collection of models 使用C#中的通用列表和接口进行类型转换-寻找一种优雅的解决方案 - Type conversion with Generic List and Interfaces in C# - Looking for an elegant solution
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM