我正在使用带有Entity Framework的asp.net mvc。 我有一个约会列表,其中包含一个beginat字段,一个endat字段和一个roomid字段(称为SpaceConfigurationId),并希望找到已为给定房间预订双重的约会列表。可以假设endat总是在startat之后。
有4种情况可以让约会匹配:
我想要满足任何这些要求的约会列表。这似乎很简单,但实际上是一个心灵游戏。我看了几眼,但似乎没有到达任何地方。 我定义了以下变量,并希望返回一个列表。
IQueryable<Appointment> appointments = Repository.ReadAppointments();
... insert code here ...
return appointments.ToList();
这是一些非常慢但可能有助于概述问题的SQL
select COUNT(*)
from appointment a
cross join appointment b
where
not a.Id = b.Id
AND
a.SpaceConfigurationId = b.SpaceConfigurationId
AND
(
(a.StartedAt < b.StartedAt and a.EndedAt > b.StartedAt and a.EndedAt < b.EndedAt)
OR
(a.StartedAt > b.StartedAt and a.StartedAt < b.EndedAt and a.EndedAt > b.EndedAt)
OR
(a.StartedAt < b.StartedAt and a.EndedAt > b.EndedAt)
OR
(a.StartedAt > b.StartedAt and a.StartedAt < b.EndedAt and a.EndedAt > b.StartedAt and a.EndedAt < b.EndedAt)
)
答案 0 :(得分:1)
有两种情况,约会不匹配:
所以..
select COUNT(*)
from appointment a
join appointment b
on
(not a.Id = b.Id)
AND
(a.SpaceConfigurationId = b.SpaceConfigurationId)
AND
NOT (a.EndetAt < b.StartedAt)
AND
NOT (a.StartedAt > b.EndetAt)
因此...
repository.ReadAppointments().Where(a => repository.ReadAppointments().
Any(b =>
!(b.ID == a.ID) &&
(a.SpaceConfigurationId == b.SpaceConfigurationId) &&
!(a.EndetAt < b.StartedAt) &&
!(a.StartedAt > b.EndetAt))).
Select(t => t.ID).ToList();
它不会生成相同的SQL。它实际上使用EXISTS
,但使用适当的索引应该可以正常工作。