8

如果我有一个包含以下列的约会表,我如何查询规则以提取在特定日期或两个日期之间发生的约会?

Appointments
------
id
name
dt_start
dt_end
rrule

例如,假设我有一个约会,从 2016 年 9 月 28 日开始,到 2017 年 4 月 28 日结束,它每 2 周在星期一、星期五发生一次,直到 2017 年 4 月 28 日。以下是 RRule:

RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=20170428T230000Z;BYDAY=MO,FR EXDATE:20170414T023000Z

因此,使用上面的示例,上述约会的某些日期将包括以下内容:

2016-09-30 FRI
2016-10-10 MO
2016-10-14 FRI
2016-10-24 MO

现在如何使用 SQL 或任何其他方法查询此表以提取 2016 年 10 月 10 日发生的所有约会?

作为记录,这将在 C# asp.net 和 SQL 服务器中完成。是否有可用于解析和查询 rrule 的 C# 或 SQL Server 库?

我查看了ICAL.net,但似乎没有太多关于它的文档,或者我将如何将它用于上述目的。

有人对 ICAL.net 有任何经验吗?

4

2 回答 2

2

有人对 ICAL.net 有任何经验吗?

不是,但我是php-rrule的作者,我认为我的回答也适用于您的情况。

让我们首先说,除非您有一组非常有限的规则,并且您知道,例如,没有事件将永远是无限的,或者重复超过 X 次或其他任何事情,否则在存储之前扩展规则是行不通的。

据我所知,你不能只用SQL来做,你必须分两步来做。

  1. 查询 2016 年 10 月 10 日之前的所有事件,dt_start以及 2016年 10 月 10 日dt_end之后的所有事件。
  2. 丢弃所有在 2016 年 10 月 10 日不会发生的事件,因为它们的规则(例如BYDAY)。为此,您将需要一个库(例如我猜是 ICAL.net),它可以快速计算该rrule字段的出现次数。

我建议您在完成此操作后缓存结果,因此对于任何后续查询,您将能够读取 2016-10-10 的缓存,而不是再次进行计算。无论何时添加、更新或删除包含 2016-10-10 的事件,您都必须注意使缓存无效dt_startdt_end

于 2016-09-29T07:46:05.023 回答
0

如果您有很多重复事件,那么数据库和应用程序需要做大量工作。在我编写的日历应用程序中,我在创建事件时扩展了规则,并将每个重复事件放在单独的行中。我添加了一个唯一的 id 字段(在 icalendar 规范中的 UID,与 id 字段分开),因此如果需要,我可以在查询中将重复事件分组在一起(重复系列中的每个事件都具有相同的唯一 ID)。然后,使用标准查询搜索日期就很容易了。如果它们在规则中,它还可以更轻松地避免包含异常,因为它们在数据库中不会有一行。

于 2016-09-28T19:26:10.787 回答