Я хотел бы выполнить поиск по событиям всех пользователей в списке и получить все времена, когда каждый пользователь свободен 30 минут или больше между 7:00 и 19:00.
Однако есть одна загвоздка: если метод помечен как «повторяющийся», т. е. бит «повторяющийся» установлен на 1, то это событие повторяется в течение 52 недель после его начала (поэтому время недоступно). Извлечение этих событий осуществляется в хранимой процедуре.
Мой код пока ниже. Правильно ли я собираюсь написать эту процедуру? Я не совсем уверен, как действовать, чтобы функция возвращалась так, как мне хотелось бы. Может ли кто-нибудь помочь мне с этим?
List<string> usernames = //List of usernames.
DateTime start = //DateTime for start of period you would like to schedule meeting
DateTime end = //DateTime for end of period
//int mins = //duration of meeting (must be 30mins or greater)
foreach (string username in usernames) {
//retrieve events for this user
var db = Database.Open("mPlan");
List<DateTime> startTimes;
List<DateTime endTimes;
// This stored procedure returns all events of a user in a given time period,
// including recurring events.
var record = db.Query("EXEC dbo.GetEvents @0, @1, @2", username, start, end);
foreach(var record in result) {
startTimes.Add(record.event_start);
endTimes.Add(record.event_end);
}
// so now I have a list of all start times and end times of events
// for one user and could save all this data in a list
}
Структура таблицы:
DECLARE @Users TABLE
(
UserID INT IDENTITY(1,1),
Username VARCHAR(32)
);
DECLARE @Groups TABLE
(
GroupID INT IDENTITY(1,1),
GroupName VARCHAR(32)
);
DECLARE @Membership TABLE
(
UserID INT,
GroupID INT
);
DECLARE @event TABLE
(
event_id INT IDENTITY(1,1),
event_start DATETIME,
event_end DATETIME,
group_id INT,
recurring BIT
);
Пример функциональности, которую я хотел бы:
Пользователь добавляет несколько пользователей из базы данных в список. Пользователь выбирает период времени, в течение которого он хотел бы встретиться со всеми этими пользователями. Мой алгоритм вычисляет все периоды времени, которые свободны для всех пользователей (т. е. время, которое подходит для встречи между всеми пользователями и составляет > 30 минут).
Дополнительная информация:
Примеры случаев:
Пользователь A пытается организовать встречу с пользователем B. Все временные интервалы бесплатно. Я хотел бы, чтобы алгоритм возвращал начало DateTime и DateTime конец всех возможных комбинаций времени начала и окончания время > 30 минут и == продолжительность (параметр).
Типичный случай: Пользователь А запланировал мероприятия на все время, кроме 18:00. 7 вечера. Он пытается организовать встречу с пользователем B в течение 1 час. У пользователя B нет организованных мероприятий - DateTime 18:00 и DateTime 7pm возвращаются, чтобы указать время начала и окончания встречи.
Повторяющийся случай: у пользователя А есть повторяющееся событие с 17:00 до 18:00 в понедельник. Он пытается организовать двухчасовую встречу в понедельник через шесть недель. Все комбинации DateTime start и DateTime end, где есть разница в 2 часа, возвращаются. Время с 17:00 до 19:00 не возвращается, так как это событие повторяющееся и происходит каждую неделю в течение 52 недель.
Вот хранимая процедура, которая извлекает все пользовательские события за заданный период времени (начало, конец):
ALTER PROCEDURE dbo.GetEvents
@UserName VARCHAR(50),
@StartDate DATETIME,
@EndDate DATETIME
AS
BEGIN
-- DEFINE A CTE TO GET ALL GROUPS ASSOCIATED WITH THE CURRENT USER
;WITH Groups AS
( SELECT GroupID
FROM Membership m
INNER JOIN Users u
ON m.UserID = u.UserID
WHERE Username = @UserName
GROUP BY GroupID
),
-- DEFINE A CTE TO GET ALL EVENTS FOR THE GROUPS DEFINED ABOVE
AllEvents AS
( SELECT e.*
FROM event e
INNER JOIN Groups m
ON m.GroupID = e.group_id
UNION ALL
SELECT e.event_id, e.title, e.description,
DATEADD(WEEK, w.weeks, e.event_start),
DATEADD(WEEK, w.weeks, e.event_end),
e.group_id, e.recurring
FROM event e
INNER JOIN Groups m
ON m.GroupID = e.group_id
CROSS JOIN
( SELECT ROW_NUMBER() OVER (ORDER BY Object_ID) AS weeks
FROM SYS.OBJECTS
) AS w
WHERE e.recurring = 1
)
-- GET ALL EVENTS WHERE THE EVENTS FALL IN THE PERIOD DEFINED
SELECT *
FROM AllEvents
WHERE Event_Start >= @StartDate
AND Event_End <= @EndDate
END