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