簡體   English   中英

Linq比較2個不同的列表並選擇外連接

[英]Linq to compare 2 different lists and select the outer join

我有2個不同的類,代表2種類型的數據。 第一個是未發布的原始格式。 第二種是發布的格式。

 public class SalesRecords
 {
    public long? RecordId { get; set; }
    public DateTime RecordDate { get; set; }
    public string RecordDesc { get; set; }

    // Other non-related properties and methods
 }

 public class PostedSalesRecords
 {
      public long? CorrelationId { get; set; }
      public DateTime RecordDate { get; set; }
      public DateTime? PostedDate { get; set; }
      public string RecordDesc { get; set; }

      // Other non-related properties and methods
 }

我們的系統有一份銷售記錄清單。 這些銷售記錄在用戶確定的時間發布到不同的系統。 我正在創建一個屏幕,顯示所有已過帳的銷售記錄以及未過帳的銷售記錄作為對帳。 我的網格的數據源將是PostedSalesRecords的列表。 我需要做的是找出List<SalesRecords>中不在List<PostedSalesRecords>哪些記錄,然后將那些未發布的SalesRecords映射到PostedSalesRecords。 我很難找到快速比較的方法。 基本上我試過這個,而且速度非常慢:

 private List<SalesRecords> GetUnpostedSalesRecords(
      List<SalesRecords> allSalesRecords,
      List<PostedSalesRecords> postedSalesRecords)
 {
      return allSalesRecords.Where(x => !(postedSalesRecords.Select(y => y.CorrelationId.Value).Contains(x.RecordId.Value))).ToList();
 }

我最大的問題是我正在過濾大量數據。 我將約55,000張總銷售記錄與約17,000張已發布的記錄進行比較。 我需要大約2分鍾來處理這個問題。 有什么方法可以加快速度嗎? 謝謝!

您可以嘗試外部聯接,請查看這是否有助於提高性能:

 var test = (from s in allSalesRecords
                join p in postedSalesRecords on s.RecordId equals p.CorrelationId into joined
                from j in joined.DefaultIfEmpty()
                where j == null
                select s).ToList();

或者在你的實現中,你可以為postingSalesRecords創建一個只有Ids的字典,然后在你的查詢中使用該集合,它肯定會有助於提高性能,因為查找時間將是O(1)而不是遍歷整個集合。記錄。

 var postedIds = postedSalesRecords.Select(y => y.CorrelationId.Value)
                                      .Distinct().ToDictionary(d=>d);
return allSalesRecords.Where(x => !(postedIds.ContainsKey(x.RecordId.Value))).ToList();

使用MSDN上描述的左外連接應該更有效:

private List<SalesRecords> GetUnpostedSalesRecords(
    List<SalesRecords> allSalesRecords,
    List<PostedSalesRecords> postedSalesRecords)
{
    return (from x in allSalesRecords
            join y in postedSalesRecords on x.RecordId.Value
                                     equals y.CorrelationId.Value into joined
            from z in joined.DefaultIfEmpty()
            where z == null
            select x).ToList();
}

這可能會使用哈希集來實現。 您可以自己實現(可以說更清楚):在一個或兩個列表中構建ID值的HashSet<long> ,以確保每次遍歷外部列表時不需要重復的O(N)查找。

暫無
暫無

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

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