簡體   English   中英

Linq單個集合中的重疊日期范圍檢查

[英]Linq Overlapped date range checking in single collection

Class TimeRange{
  private DateTime StartDate{get; set;}
  private DateTime EndDate{get; set;}
}

List<TimeRange> TimeRangeList = new List<TimeRange>(){
  new TimeRange(){StartDate = new DateTime(2050, 1, 1), 
                    EndDate = new DateTime(2050, 1, 10)},
  new TimeRange(){StartDate = new DateTime(2050, 2, 1), 
                    EndDate = new DateTime(2050, 2, 10)},
  //This item will triggered the overlap validation failed
  new TimeRange(){StartDate = new DateTime(2050, 1, 5),
                    EndDate = new DateTime(2050, 1, 9)},
                              },
}

因此,在我檢查了類似的主題之后 ,我仍然無法弄清楚檢查重疊的日期范圍的算法。

根據檢查多個日期范圍對象之間的日期重疊 ,這在SQL中非常簡單

我只需要比較兩個日期范圍

SELECT COUNT(*)
FROM Table1
WHERE Table1.StartDate < 'endCheckDate'
AND Table1.EndDate > 'startCheckDate'

我發現在Linq中很難做到,我們如何比較其中一個集合中的所有項目? 原因是我們可以像比較兩個列表一樣在循環中使用foreach,但是在select中如何工作?

其實我在做這樣的事情

for (int i = 0; i < TimeRangeList .Count(); ++i)
{
        var item = TimeRangeList[i];                    
        for (int y = i + 1; y < TimeRangeList.Count(); ++y)
        {
                var item2 = TimeRangeList[y];

                if (IsOverLapped(item, item2))
                {
                    // this is overlapped
                };
        }
}

private bool IsOverLapped(dynamic firstObj, dynamic secondObj)
{
        return secondObj.StartDate <= firstObj.EndDate && firstObj.StartDate <= secondObj.EndDate;
}

還有沒有循環的更優雅的方法嗎?

所以我的問題是,我們如何通過linq比較每個項目本身的單個列表?

一個簡單的蠻力想法:

bool overlap = TimeRangeList
    .Any(r => TimeRangeList
         .Where(q => q != r)             
         .Any(q => q.EndDate >= r.StartDate && q.StartDate <= r.EndDate) );

如果我看一下您的SQLcode,看來您有一個Table1對象,它是一系列相似對象的序列,比方說Table1Row類。 每個Table1Row至少具有兩個DateTime屬性,即StartDateEndDate 此外,您還有兩個DateTime對象: startCheckDateendCheckDate

您要計算Table1中所有StartDate小於startCheckDateEndDate大於endCheckDate

編寫為IQueryable的擴展功能:

public static int CountOverlapping(this IQueryable<Table1Row> table1,
    DateTime startCheckDate,
    DateTime endCheckDate)
{
    return table1
        .Where (row => row.StartDate < startCheckDate && row.EndDate > endCheckDate)
        .Count();
}

用法:

DateTime startCheckDate = ...
DateTime endCheckDate = ...
IQueryable<Table1Row> table1 = ...
int nrOfOverlapping = table1.CountOverlapping(startCheckDate, endCheckDate);

簡單的漫畫卓悅?

暫無
暫無

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

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