SQL / C中的营业时间#

时间:2010-06-07 20:50:11

标签: c# sql linq-to-sql

出于某种原因,我在这个上面放了一个大脑屁。 我有一张桌子,上面写着“营业时间”。 该表有: - 日(星期一= 1,星期日= 7) - 开始时间 - 结束时间

我正在试图弄清楚如何编写最干净的代码(使用Linq to SQL),它将检查新小时的提交时间是否重叠并相应地修改所有记录。 例如,如果数据库已有这些记录: - 开始=早上8点,结束=中午 - 开始=下午2点,结束=下午5点

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

我希望代码能够弄清楚如何组合这3条记录并留下一条记录。但是我还需要能够在必要时才进行组合,以便有人插入此代码: - 开始=中午,结束=下午1点

然后我最终得到2条记录(第一条记录会被修改)。

像我说的那样......我似乎无法绕过这个。 帮助

1 个答案:

答案 0 :(得分: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;
}

然后你只需要找到与你的新时间间隔重叠的任何TimeInterval。您必须知道新间隔可以扩展任何现有间隔,甚至可以连接两个单独的间隔,或者仅包含在已定义的间隔内。

要获取在间隔开始时重叠的记录,请使用以下查询:

var startOverlap = (from rec in intervals
    where rec.StartMinuteInWeek() <= timeInterval.StartMinuteInWeek() && rec.EndMinuteInWeek() >= timeInterval.StartMinuteInWeek()
    select rec).FirstOrDefault();

timeInterval是您尝试添加的新区间。

结束重叠使用以下一个:

var endOverlap = (from rec in intervals
    where rec.StartMinuteInWeek() <= timeInterval.EndMinuteInWeek() && rec.EndMinuteInWeek() >= timeInterval.EndMinuteInWeek()
    select rec).FirstOrDefault();

如果startOverlap为null,则在间隔的开始处没有重叠。对于endOverlap也是如此。 如果startOverlap == endOverlap,则新间隔完全包含在已存在的间隔内。

我已经将StartTime定义为DateTime类型,虽然我只对时间部分感兴趣,如果你想要两个名为Hour and Minute的字段,或者可能只有一个代表起始分钟的字段,你可以改变它。间隔的一周。

修改

正如我在评论中提到的,我意识到新的时间间隔可以重叠几个已定义的时间间隔。例如,如果通常操作从8:00到20:00并且在午餐时间停止,现在定义了一个新的时间间隔,该时间间隔全天24x7,那么新的时间间隔将包含14个间隔。

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

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

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();

现在你必须确保新的间隔限制是正常的。

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

最后,您可以删除overlaps中的所有间隔,然后插入newInterval