使用实体框架重叠约会

时间:2010-03-02 23:54:26

标签: c# asp.net .net asp.net-mvc entity-framework

我正在使用带有Entity Framework的asp.net mvc。 我有一个约会列表,其中包含一个beginat字段,一个endat字段和一个roomid字段(称为SpaceConfigurationId),并希望找到已为给定房间预订双重的约会列表。可以假设endat总是在startat之后。

有4种情况可以让约会匹配:

  1. 约会a开始开始约会b 并在约会b开始后和约会b结束之前结束
  2. 约会a开始约会b开始后约会b结束并在约会b结束后结束
  3. 约会a开始开始约会b 并在约会b结束后结束
  4. 约会a开始约会b开始后约会b结束并在约会b开始后和约会b结束之前结束
  5. 我想要满足任何这些要求的约会列表。这似乎很简单,但实际上是一个心灵游戏。我看了几眼,但似乎没有到达任何地方。 我定义了以下变量,并希望返回一个列表。

    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)
        )
    

1 个答案:

答案 0 :(得分:1)

  1. 在SpaceConfigurationId和日期列上定义索引。
  2. 有两种情况,约会不匹配:

    1. 当a结束时b。
    2. 在b。
    3. 之后开始
  3. 所以..

    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,但使用适当的索引应该可以正常工作。