簡體   English   中英

尋找更優雅的LINQ解決方案

[英]Looking for a more elegant LINQ solution

我試圖找出一種有效的方法來檢索我想要的數據。 我需要通過ParentId獲取所有最近子項的列表,以及所有沒有子項的父項。 我創建了一個直觀的指南來說明應采取的措施。

在所有排序和分頁完成之前,查詢需要保持為IQueryable。 LINQ to Entities不支持LastLastOrDefault (如我在使用它們時收到的錯誤消息所述)。

使用FirstFirstOrDefault將返回錯誤“ This method or operation is not implemented

原始數據:

-------------------------------
- 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 -
-------------------------------

查詢返回的數據

-------------------------------
- Id - ParentId - CreatedDate -
-------------------------------
-  3 -          -  07/01/2013 -
-  6 -        2 -  07/04/2013 -
-  7 -        1 -  07/05/2013 -
-------------------------------

目前,我的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);

后端將Npgsql2與PostgreSQL一起使用。 我正在為此查詢尋找更優雅的解決方案。 我對LINQ非常陌生,想對此進行優化。

排序代碼(草率,但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);
}

分頁代碼:

var result = pageSize > 0
           ? q1.Skip(startIndex).Take(pageSize).ToList()
           : q1.ToList();

使用分組:

模擬數據:

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

查詢:

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結果:

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 

我可以提出一個不同的查詢,仍然分兩個階段

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM