C# SQL/C中的营业时间#

C# SQL/C中的营业时间#,c#,sql,linq-to-sql,C#,Sql,Linq To Sql,不知什么原因,我在这上面放了个大屁。 我有一张有“营业时间”的桌子。 该表包括: -日(周一=1,周日=7) -开始时间 -结束时间 我试图找出如何编写最干净的代码(使用LINQtoSQL),以检查提交新小时时的小时数是否重叠,并相应地修改所有记录。 例如,如果数据库已经有以下记录: -开始=上午8点,结束=中午 -开始=下午2点,结束=下午5点 有人补充说: -开始=中午,结束=下午6点 我想让代码找出如何组合这3条记录,并留给我一条记录。但我还需要在必要时才能进行组合,因此如果有人插入以下内

不知什么原因,我在这上面放了个大屁。 我有一张有“营业时间”的桌子。 该表包括: -日(周一=1,周日=7) -开始时间 -结束时间

我试图找出如何编写最干净的代码(使用LINQtoSQL),以检查提交新小时时的小时数是否重叠,并相应地修改所有记录。 例如,如果数据库已经有以下记录: -开始=上午8点,结束=中午 -开始=下午2点,结束=下午5点

有人补充说: -开始=中午,结束=下午6点

我想让代码找出如何组合这3条记录,并留给我一条记录。但我还需要在必要时才能进行组合,因此如果有人插入以下内容: -开始=中午,结束=下午1点

然后我将得到2条记录(第一条记录将被修改)

就像我说的…我就是不知道该怎么办。
帮助?

我建议您对时间间隔表示法稍作修改,使用Length属性而不是EndTime属性

class TimeInterval
{
    public int Day { set; get; }
    public DateTime StartTime { set; get; }
    public int Length { set; get; }
}
由于我们对寻找重叠的时间间隔感兴趣,接下来的方法将很方便,我将把它们放在TimeInterval类中

public int StartMinuteInWeek()
{
    return Day * 24 * 60 + StartTime.Hour * 60 + StartTime.Minute;
}

public int EndMinuteInWeek()
{
    return StartMinuteInWeek() + Length;
}
public bool IsInsideInterval(int minuteInWeek)
{
    return minuteInWeek >= StartMinuteInWeek() &&
        minuteInWeek <= EndMinuteInWeek();
}
然后,您只需要找到与新时间间隔重叠的任何时间间隔。您必须知道,新的间隔可以扩展任何现有的间隔,甚至可以连接两个单独的间隔,或者只包含在已定义的间隔中

var overlaps = (from rec in intervals where
    newInterval.IsInsideInterval(rec.StartMinuteInWeek()) ||
    newInterval.IsInsideInterval(rec.EndMinuteInWeek())
    select rec).ToList();
要获取在间隔开始时重叠的记录,请使用以下查询:

var startOverlap = (from rec in intervals
    where rec.StartMinuteInWeek() <= timeInterval.StartMinuteInWeek() && rec.EndMinuteInWeek() >= timeInterval.StartMinuteInWeek()
    select rec).FirstOrDefault();
如果startOverlap为空,则在间隔的开始处没有重叠。endOverlap也一样。 如果startOverlap==endOverlap,则新间隔完全包含在已存在的间隔内

var overlaps = (from rec in intervals where
    newInterval.IsInsideInterval(rec.StartMinuteInWeek()) ||
    newInterval.IsInsideInterval(rec.EndMinuteInWeek())
    select rec).ToList();
我已经将StartTime定义为DateTime类型,虽然我只对时间部分感兴趣,但是如果您想更改两个名为Hour和Minute的字段,或者只更改一个表示间隔周中开始分钟的字段,则可以更改此字段

var overlaps = (from rec in intervals where
    newInterval.IsInsideInterval(rec.StartMinuteInWeek()) ||
    newInterval.IsInsideInterval(rec.EndMinuteInWeek())
    select rec).ToList();
编辑

正如我在评论中提到的,我已经意识到一个新的时间间隔可以与几个已经定义的时间间隔重叠。例如,如果正常情况下,操作从8:00到20:00,并在午餐时间停止,现在定义了一个新的时间间隔,该时间间隔将贯穿整个星期的24x7,那么新的时间间隔将包含14个时间间隔

一种安全的方法是首先检测所有重叠的间隔,然后调整新间隔以确保它完全包含任何重叠的间隔,最后删除所有重叠

为了找出新的间隔是否与旧的重叠,我将在TimeInterval类中定义这个方便的方法

public int StartMinuteInWeek()
{
    return Day * 24 * 60 + StartTime.Hour * 60 + StartTime.Minute;
}

public int EndMinuteInWeek()
{
    return StartMinuteInWeek() + Length;
}
public bool IsInsideInterval(int minuteInWeek)
{
    return minuteInWeek >= StartMinuteInWeek() &&
        minuteInWeek <= EndMinuteInWeek();
}
现在你必须确保新的间隔限制是正确的

foreach (TimeInterval rec in overlaps)
{
    if (rec.StartMinuteInWeek() < newInterval.StartMinuteInWeek())
    {
        newInterval.Day = rec.Day;
        newInterval.StartTime = rec.StartTime;
    }
    if (rec.EndMinuteInWeek() > newInterval.EndMinuteInWeek())
    {
        // You have to calc the Length being careful to not count twice the minutes that overlaps.
        newInterval.Length = newInterval.Length + rec.Length - (newInterval.EndMinuteInWeek() - rec.StartMinuteInWeek());
    }
}
foreach(重叠的时间间隔rec)
{
如果(记录StartMinuteInWeek()newInterval.EndMinuteInWeek())
{
//您必须计算长度,注意不要计算重叠的分钟数的两倍。
newInterval.Length=newInterval.Length+rec.Length-(newInterval.EndMinuteInWeek()-rec.StartMinuteInWeek());
}
}

最后,您可以删除
重叠中的所有间隔
,然后插入
新间隔

,我刚刚意识到问题比我最初想的要复杂一些。一个新的时间间隔可以与几个已定义的时间间隔重叠。我正在更新!