我想从我的数据库中DateTime
的可用列表中找到常见的DateTime
。
背景
让我们假设,
我想见到一些人,我说我希望在Datetime X(2014-02-16 09:00:00.000)到DateTime Y(2014-02-26 05:00:00.000)之间遇到某些人。
然后我想见的人将回复说我将在以下日期提供:Date1(从某个开始时间到某个结束时间的某个日期),Date2(从某个时间到某个时间的特定日期),...等等。
让我们考虑这些是回应
Attendee1
(有些GuidId):
Response1
:开始时间= 2014-02-23 09:00 AM,EndTime = 2014-02-17 11:00 AM,
Response2
:开始时间= 2014-02-24 10:00 AM,结束时间= 2014-02-17 12:00 PM,
Response3
:开始时间= 2014-02-25 10:00 AM,EndTime = 2014-02-17 11:00 AM,
Response4
:开始时间= 2014-02-23 01:00 PM,EndTime = 2014-02-17 5:00 PM
Attendee2
(有些GuidId):
Response1
:开始时间= 2014-02-22 09:00 AM,EndTime = 2014-02-17 05:00 PM,
Response2
:开始时间= 2014-02-23 09:00 AM,EndTime = 2014-02-17 05:00 PM,
Response3
:开始时间= 2014-02-25 09:00 AM,EndTime = 2014-02-17 12:00 PM,
Attendee3
(有些GuidId):
Response1
:开始时间= 2014-02-22 11:00 AM,EndTime = 2014-02-17 02:00 PM,
Response2
:开始时间= 2014-02-23 04:00 PM,EndTime = 2014-02-17 03:00 PM,
Response3
:开始时间= 2014-02-23 04:00 PM,EndTime = 2014-02-17 05:00 PM,
Response4
:开始时间= 2014-02-24 02:00 AM,EndTime = 2014-02-17 05:00 PM,
Response5
:开始时间= 2014-02-25 11:00 AM,EndTime = 2014-02-17 12:00 PM,
此处,在上述场景中,系统应提供匹配日期:
2014-02-23 04:00 PM to 2014-02-23 05:00 PM
和
2014-02-25 11:00 AM to 2014-02-25 12:00 PM
所以每一个人都回复了。我想找到共同的DateTime
或共同List<DateTime>
(如果存在)。
或者找到匹配次数最多的DateTime(List)
。
我知道我必须展示我所尝试过的以及我所做的事情,但我不知道我应该如何开始。
任何建议或提示都将不胜感激。
修改1 :
因此,在数据库中有一个名为Appointment
的表,用于存储StartDateTime
和EndDateTime
public class Appointment
{
[Key]
public Guid Id { get; set; }
public virtual ICollection<Attendee> Attendees { get; set; }
public DateTime StartDateTime { get; set; }
public DateTime EndDateTime { get; set; }
}
在这些日期之间,参加会议的人(参加者)将给予回复。
每个人(谁都会回复),他们的信息都存储在名为Attendees
public class Attendee
{
public Guid AttendeeId { get; set; }
public virtual ICollection<Response> Responses { get; set; }
}
对于每个用户,他们的响应存储在Responses
表中,其模型看起来像
public class Response
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public Guid AttendeeId { get; set; }
public DateTime StartDateTime { get; set; }
public DateTime EndDateTime { get; set; }
}
PS :
它是MVC application
,数据库是使用code first approach
创建的。
另外,将AppointmentId
添加到Response
表是否有意义?或者那是不好的方法?但我认为这会使查询更容易。
答案 0 :(得分:1)
可能有效的方法:
可能需要一些触摸来处理边缘情况,但以下代码应该让您走上正确的道路:
public class MeetingTime
{
DateTime Start { get; set; }
DateTime End { get; set; }
List<Response> Responses { get; set; }
public int NumAttendees
{
get { return Responses.Select(x => x.AttendeeId).Distinct().Count(); }
}
public MeetingTime(Response response)
{
Start = response.StartDateTime;
End = response.EndDateTime;
Responses = new List<Response>();
}
public void MergeMeetingTime(Response response)
{
// if response times are within current times, can be merged
if (Start <= response.StartDateTime && response.EndDateTime <= End)
{
Start = response.StartDateTime;
End = response.EndDateTime;
Responses.Add(response);
}
}
}
public List<MeetingTime> FindMeetingTimes()
{
var attendees = GetAttendees();
var times = new List<MeetingTime>
bool isFirstAttendee = true;
foreach (Attendee attendee in attendees)
{
if (isFirstAttendee)
{
foreach (Response response in attendee.Responses)
{
times.Add(new MeetingTime(response));
}
isFirstAttendee = false;
}
else
{
// Go through attendee.Responses and compare each with the current times
// for each one, if it overlaps with a MeetingTime, then adjust
// the Start/End dates accordingly and increment Count
// Uses same approach as above.
foreach (Response response in attendee.Responses)
{
times.ForEach(x => x.MergeMeetingTime(response));
}
}
}
// Remove all times where not everyone can attend
times.Remove(x => x.NumAttendees < attendees.Count()).ToList();
return times;
}
最后,您删除所有不是每个人都可以参加的时间。剩下的时间应该都包含所有参加者可以制作的开始/结束日期时间。