C# 使用实体框架的重叠任命
我正在使用asp.NETMVC和实体框架。 我有一个带有startedat字段、endedat字段和roomid字段(称为SpaceConfigurationId)的约会列表,我想查找已为给定房间双重预订的约会列表。可以假设endedat总是在startedat之后 有4种情况允许匹配预约:C# 使用实体框架的重叠任命,c#,asp.net,.net,asp.net-mvc,entity-framework,C#,Asp.net,.net,Asp.net Mvc,Entity Framework,我正在使用asp.NETMVC和实体框架。 我有一个带有startedat字段、endedat字段和roomid字段(称为SpaceConfigurationId)的约会列表,我想查找已为给定房间双重预订的约会列表。可以假设endedat总是在startedat之后 有4种情况允许匹配预约: 约会a在约会b开始之前开始,在约会b开始之后和约会b结束之前结束 约会a在约会b开始后和约会b结束前开始,在约会b结束后结束 约会a在约会b开始之前开始,在约会b结束之后结束 约会a在约会b开始之后和约会b
IQueryable<Appointment> appointments = Repository.ReadAppointments();
... insert code here ...
return appointments.ToList();
IQueryable约会=Repository.readappoints();
... 在这里插入代码。。。
返回约会。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)
)
选择计数(*)
从预约
交叉加入预约b
哪里
非a.Id=b.Id
及
a、 SpaceConfigurationId=b.SpaceConfigurationId
及
(
(a.StartedAtb.StartedAt和a.EndedAtb.StartedAt和a.StartedAtb.EndedAt)
或
(a.StartedAtb.EndedAt)
或
(a.StartedAt>b.StartedAt和a.StartedAtb.StartedAt和a.EndedAt
选择计数(*)
从预约
加入约会b
在…上
(非a.Id=b.Id)
及
(a.SpaceConfigurationId=b.SpaceConfigurationId)
及
不是(a.结束b.结束)
所以
repository.readappoinces()。其中(a=>repository.readappoinces()。
任何(b=>
!(b.ID==a.ID)和
(a.SpaceConfigurationId==b.SpaceConfigurationId)&&
!(a.结束b.结束)。
选择(t=>t.ID).ToList();
它不会生成相同的SQL。它实际上使用的是EXISTS
,但是使用适当的索引应该可以
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();