构建最有效查询的查询如果某个日期范围在某个区间内?

时间:2011-03-10 19:03:35

标签: c# .net linq intervals

DateRange1和DateRange2之间存在重叠

DateRange1:        |-----------|
DateRange2:                |-------|

DateRange3和DateRange4

之间不存在重叠
DateRange3:    |------|
DateRange4:                 |-------|

我有一个查询,检查是否有重叠,但它有点毛茸茸。它涉及检查每个DateRange边框并使用很多<'s和>'。

我想知道你是否可以这么说,如果DateRange1.Union(DateRange2)!= null,那就去做吧。 只是让我的代码更具可读性和更少毛茸茸的东西。

谢谢!

2 个答案:

答案 0 :(得分:1)

如果您可以添加IncludedDates属性(IEnumerable<DateTime>),那应该非常简单。

DateRange1.IncludedDates.Intersect(DateRange2.IncludedDates).Any()

答案 1 :(得分:1)

我创建了一个扩展方法:

public static bool OverlappedTo(this DateRange range1, DateRange range2)
{
    return range1.OverlappedTo(range2.Start, range2.End);
}

// Just an example, implement as you prefer...
public bool OverlappedTo(this DateRange range1, DateRange range2)
{
    var duration1 = range1.End - range1.Start;
    var duration2 = range2.End - range2.Start;

    var minStart = range1.Start < range2.Start ? range1.Start : range2.Start;
    var maxEnd = range1.End > range2.End ? range1.End : range2.End;

    var totalDuration = maxEnd - minStart;

    // if the sum of the 2 durations is less than 
    // the total duration --> overlapped
    return duration1 + duration2 < totalDuration;
}

用法:

bool overlapped = range1.OverlappedTo(range2);

<强> P.S。

我的DateRange课程与此相似:
(也许你有另一个实现)

public class DateRange
{
    public DateTime Start { get; private set; }
    public DateTime End { get; private set; }

    public DateRange(DateTime start, DateTime end)
    {
        this.Start = start;
        this.End = end;
    }
}

修改
(根据评论)

var outSideRange = new DateRange(start, end);

var filteredRows = 
dt.AsEnumerable()
  .Where(x => outSideRange.OverlappedTo(x.Field<DateTime>("StartCol"),
                                        x.Field<DateTime>("EndCol")));