2016-09-28 10 views
0

Если у меня есть таблица встреч со следующими столбцами, как я могу запросить rrule, чтобы вытащить встречи, которые происходят в определенную дату или между двумя датами?Как запросить повторяющиеся встречи, сохраненные как iCal RRULE в таблице базы данных?

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

Так, например, позволяет сказать, что у меня назначена встреча, которая начинается на 2016-09-28 и заканчивается на 2017-04-28 и не происходит каждые 2 недели в понедельник, в пятницу до 28 апреля 2017. Ниже будет быть 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-сервере. Есть ли библиотека C# или SQL Server, которую я могу использовать для анализа и запроса rrule?

Я просмотрел ICAL.net, но, похоже, на нем нет документации или как бы я использовал его для этой цели, как описано выше.

Есть ли у кого-нибудь опыт работы с ICAL.net?

+0

Ваш переход должен разделить строку и извлечь различные части, построить таблицу дат между вашим началом и концом (рекурсивный cte) или измерение даты было бы хорошо. затем используйте кучу аргументов case для определения всех комбинаций дат, интерфейса, дней недели, конца месяца, первого четверга месяца и т. д. ... это не будет легкой задачей, но выполнимо. – Matt

ответ

0

Это большая работа для работы с базой данных и приложениями, если у вас много повторяющихся событий. В приложении календаря, которое я написал, я расширил правило при создании события и каждое повторяющееся событие в отдельной строке. Я добавил уникальное поле id (UID в спецификации icalendar, отдельно от поля id), поэтому я могу группировать повторяющиеся события вместе в запросе, если это необходимо (каждое событие в повторяющейся серии имеет тот же уникальный идентификатор). Тогда легко найти даты, используя стандартный запрос. Это также облегчает исключение исключений, если они находятся в правиле, в котором не было бы строки в базе данных.

+0

вы можете привести пример своей схемы базы данных? Разве каждое повторяющееся событие не раздувает базу данных? Допустим, что есть событие без даты окончания, но повторяется бесконечно - это позволит быстро использовать все пространство для хранения базы данных. Обратитесь к следующим документам: https://github.com/bmoeskau/Extensible/blob/master/recurrence-overview.md – adam78

+0

Когда я создаю событие, я использую диапазон дат, который ограничивает повторяющиеся даты до определенного периода времени, как 1 год назад до 3 лет с этого момента, тогда у вас есть функция для расширения/удаления повторяющихся дат с течением времени. Не самое лучшее, но запросы быстры. Недостаточно места для отображения схемы таблиц, но вы можете загрузить бесплатную версию Zap Calendar Lite, которая имеет эту функцию, и посмотреть на код (требуется Joomla) http://zcontent.net/products/zap-calendar-lite – zcontent

0

Есть ли у кого-нибудь опыт работы с ICAL.net?

Не, но я являюсь автором php-rrule, и я думаю, что мой ответ будет применим и к вашей ситуации.

Начнем с того, что, если у вас нет очень ограниченного набора правил, и вы знаете, например, что ни одно событие никогда не будет бесконечным или повторяться больше, чем X раз или что-то еще, расширение правила до того, как хранилище не будет идти на работу.

Насколько я знаю, вы не можете сделать это только в SQL, вам нужно сделать это за два шага.

  1. Запрос все события, где dt_start является или до того 2016-10-10 и dt_end является или после 2016-10-10.
  2. Отбросьте все события, которые не произойдут в 2016-10-10 из-за их правила (например, BYDAY). Для этого вам понадобится библиотека (например, ICAL.net, я думаю), которая может быстро рассчитать события из поля rrule.

Я рекомендую вам кэшировать результат, как только это будет сделано, поэтому для любого последующего запроса вы сможете прочитать кеш для 2016-10-10 вместо повторного вычисления. Вы должны позаботиться об аннулировании кеша в любое время, когда событие, которое включает 2016-10-10 между dt_start и dt_end, добавлено, обновлено или удалено.