【问题标题】:overlapping appointments using the entity framework使用实体框架重叠任命
【发布时间】:2010-03-02 23:54:26
【问题描述】:

我正在使用带有实体框架的 asp.net mvc。 我有一个约会列表,其中包含一个 startat 字段、一个 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结束之前

我想要满足任何这些要求的约会列表。这看起来很简单,但实际上是一个智力游戏。我看了一下 intersect 但似乎没有得到任何地方。 我定义了以下变量并希望返回一个列表。

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

【问题讨论】:

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


    【解决方案1】:
    1. 在 SpaceConfigurationId 和日期列上定义索引。
    2. 约会不匹配有两种情况:

      1. 当 a 在 b 之前结束时。
      2. 当 a 在 b 之后开始时。

    所以..

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

    【讨论】:

      猜你喜欢
      • 2018-10-05
      • 1970-01-01
      • 1970-01-01
      • 2011-02-18
      • 1970-01-01
      • 2011-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多