簡體   English   中英

Linq-to-Entities 包含並排序

[英]Linq-to-Entities contains and order by

我使用 EF Core,我只想選擇我需要的 ID,我會這樣做,我使用In SQL 表達式。 如何以與數組中的 ID 相同的順序獲得結果? 並在結果 Dto 中填寫OrderNum值?

public IEnumerable<ResultDto> Foo()
{
    int[] validIds = { 100, 2, 3, 4, 5, 6, 8, 13, 14, 16, 22 };

    // Without the required sorting
    var query = dc.LeaveRequests.Where(x => validIds.Contains(x.Id));

   ...
}

class Model
{
     public int Id { get; set; }
     public string Name { get; set; }
}

class ResultDto
{
     public int Id { get; set; }
     public string Name { get; set; }
     public int OrderNum { get; set; }
}

我將創建一個索引查找字典,其中 ID 作為鍵,索引作為值。 然后,您可以通過在 O(1) 時間內在字典中查找索引來對結果進行排序。 (在數組上使用.IndexOf將是 O(n) 操作)

int[] validIds = { 100, 2, 3, 4, 5, 6, 8, 13, 14, 16, 22 };
var result = dc.LeaveRequests.Where(x => validIds.Contains(x.Id)).AsEnumerable();
    
var indexLookup = validIds.Select((v,i) => (v,i)).ToDictionary(x => x.v, x => x.i);
var sortedResult = result.OrderBy(x => indexLookup[x.Id]);

也許更簡單的解決方案是將validIds 與查詢結果join起來。 保留第一個集合的順序,連接將在內部使用 HashSet 進行查找。 由於可以避免使用OrderBy對結果進行排序,因此它的性能也會更好。

int[] validIds = { 100, 2, 3, 4, 5, 6, 8, 13, 14, 16, 22 };
var result = dc.LeaveRequests.Where(x => validIds.Contains(x.Id)).AsEnumerable();

var sortedResult = validIds.Join(result, x => x, x => x.Id, (x, y) => y);

如果您沒有更多要求,請嘗試OrderBy

var query = dc.LeaveRequests
     .Where(x => validIds.Contains(x.Id))
     .OrderBy(x => validIds.IndexOf(x.Id))
     .Select(x => new OrderNum {
          Id = x.Id,
          Name = x.Name,
          OrderNum = //fill OrderNum here,

     })
     .AsEnumerable();

假設有效 id 可能以另一種順序提供,您可以按 id 在validIds中的索引位置排序(使用列表而不是數組)並將結果的索引位置映射到OrderNum屬性:

var query = dc.LeaveRequests
    .Where(x => validIds.Contains(x.Id))
    .OrderBy(x => validIds.IndexOf(x.Id))
    .Select((x, i) => new ResultDto
    {
        Id = x.Id,
        Name = x.Name,
        OrderNum = i
    });
var results = dc.LeaveRequests
    .Where(x => validIds.Contains(x.Id))
    .Select(x => new ResultDto
    {
        Id = x.Id,
        Name = x.FechaCreacion,
    })
    .AsEnumerable()
    .OrderBy(x => validIds.IndexOf(x.Id))
    .ToList();

for (int i = 0; i < results.Count; i++)
{
    results[i].OrderNum = i;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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