简体   繁体   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)},
                              },
}

so after I checked out the similar topic , I still can't figured out the algorithm of checking the overlapped date range. 因此,在我检查了类似的主题之后 ,我仍然无法弄清楚检查重叠的日期范围的算法。

This is quite simple in SQL, according to Checking for date overlap across multiple date range objects 根据检查多个日期范围对象之间的日期重叠 ,这在SQL中非常简单

I just need to compare two date range like this 我只需要比较两个日期范围

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

I found it is difficult to do in Linq, how do we compare all items in one collection within? 我发现在Linq中很难做到,我们如何比较其中一个集合中的所有项目? of cause we can use foreach in just loop the collection just like comparing two list, but how is it work in select? 原因是我们可以像比较两个列表一样在循环中使用foreach,但是在select中如何工作?

actually I'm doing something like this 其实我在做这样的事情

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

Is there a more elegant way to do without looping? 还有没有循环的更优雅的方法吗?

so my questions is how do we compare one single list for each items itself by linq? 所以我的问题是,我们如何通过linq比较每个项目本身的单个列表?

A simple brute force idea: 一个简单的蛮力想法:

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

If I look at your SQLcode, it seems that you have a Table1 object which is a sequence of similar objects, let's say of class Table1Row . 如果我看一下您的SQLcode,看来您有一个Table1对象,它是一系列相似对象的序列,比方说Table1Row类。 Every Table1Row has at least two DateTime properties, a StartDate and an EndDate . 每个Table1Row至少具有两个DateTime属性,即StartDateEndDate Furthermore you have two DateTime objects: startCheckDate and endCheckDate . 此外,您还有两个DateTime对象: startCheckDateendCheckDate

You want to count all elements in your Table1 that have a StartDate smaller than startCheckDate and an EndDate larger than endCheckDate 您要计算Table1中所有StartDate小于startCheckDateEndDate大于endCheckDate

Written as an extension function of IQueryable: 编写为IQueryable的扩展功能:

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

Usage: 用法:

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

Simple comme bonjour? 简单的漫画卓悦?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM