【问题标题】:Find bookings that conflict with given arrival / departure dates查找与给定到达/离开日期冲突的预订
【发布时间】:2019-02-25 04:02:28
【问题描述】:

我有一个名为 Bookings 的表格,其中包含以下列:-

RoomId (int)
ArrivalDate (datetime)
DepartureDate (datetime)

我遇到的问题是检查已创建的预订。下面的例子。

预订 1 - 1 晚
到达日期 = 17/09/2018
出发日期 = 18/09/2018

预订 2 - 2 晚
到达日期 = 18/09/2018
出发日期 = 20/09/2018

预订 3 - 4 晚
到达日期 = 21/09/2018
出发日期 = 25/09/2018

因此,从 2018 年 9 月 20 日到 2018 年 9 月 21 日的 1 晚预订可用。

我的困难是找到正确的查询来应对以下情况。

预订 4 - 3 晚
到达日期 = 20/09/2018
出发日期 = 23/09/2018

这将失败,因为预订 3 已被 21/09/2018 和 22/09/2018 占用。

预订 5 - 7 晚
到达日期 = 20/09/2018
出发日期 = 27/09/2018

这将失败,因为预订 3 已预订 21/09/2018、22/09/2018、23/09/2018 和 24/09/2018。但是,25/09/2018 和 26/09/2018 可用

我已经编写了一个函数来检查是否可以进行预订,尽管它目前失败了。

var o = await dc.Bookings.Where(c =>
    c.RoomId == roomId && c.IsDeleted == false  &&
    (c.ArrivalDate > arrivalDate && c.DepartureDate < departureDate)).CountAsync();

Select * From Bookings Where RoomId = 1 And
    (ArrivalDate Between '2018-09-20 00:00:00.000' And '2018-09-21 00:00:00.000') Or
    (DepartureDate Between '2018-09-20 00:00:00.000' And '2018-09-21 00:00:00.000') Or
    (ArrivalDate >= '2018-09-20 00:00:00.000' And DepartureDate <= '2018-09-21 00:00:00.000')

我整天都在做这件事,但一直想不通。任何指向正确方向的指针将不胜感激。

【问题讨论】:

  • this 有帮助吗?
  • 什么查询不起作用? EF、SQL 还是两者兼而有之?

标签: c# sql entity-framework linq date


【解决方案1】:

此查询将查找与指定到达和离开日期重叠的预订。它假定出发日期是唯一的(即客人可以在前一位客人离开的那天到达):

SELECT *
FROM Bookings
WHERE RoomId = 1 AND @DepartureDate > ArrivalDate AND DepartureDate > @ArrivalDate
-- @Arrival/Departure dates are the ones you want to check

All of your three tests here

鉴于此查询,查找可用房间很简单。

【讨论】:

  • 谢谢你。这几乎是另一个正在制作的扳手。如果我已经在 2018 年 9 月 21 日预订了 1 晚的预订,但我想更新此预订并在其中添加额外的日期,查询显然会返回结果。我将如何应对更新说,相同的到达日期但出发日期是 24/09/2018?
  • 对不起,我不明白。您是说系统将预订标记为与自身冲突吗?然后只需添加Other.IDBooking &lt;&gt; ToUpdate.IDBooking。 @戴恩
  • 不抱歉。我进行了预订,我们称其为 Id=1。但我想更新此预订以增加额外的天数,而不是 1 晚,我想将其更新为 3 晚。但是,我不想创建新的预订,而是想更新它,但仍然检查可用性,以防其他日期不可用。 @萨尔曼A
  • 您仍将使用相同的查询来检查之前更新的冲突:SELECT * FROM Bookings WHERE RoomId = 1 AND '24/09/2018' &gt; ArrivalDate AND DepartureDate &gt; '21/09/2018' AND Id &lt;&gt; 1。请注意,我添加了Id &lt;&gt; 1,因为预订总是会与自身发生冲突;您只想检查其他人。
  • 非常感谢@Salman,很高兴。非常感谢您的帮助。
【解决方案2】:

如果您想同时进行其他预订:

Select b.*
From Bookings
Where RoomId = 1 And 
      ArrivalDate <= '2018-09-21' and
      DepartureDate >= '2018-09-20';

逻辑很简单。如果一个周期在第二个周期结束时或之前开始,则两个周期重叠。并且,第一个在第二个开始时或之后结束。这假设周期包括终点。如果&lt;=(到&lt;)和&gt;=(到&gt;)是独占的,你可以调整它们。

如果这没有返回任何记录,则该期间 (2018-09-20 - 2018-09-21) 可免费用于新预订。

【讨论】:

  • 戈登,你在这里展示什么?这个查询可能会输出 Booking 3,表明他不能预订今晚的,而实际上他可以?
  • @DerrickMoeller 。 . .这是在给定时间段内返回冲突。如果查询没有返回结果,则没有冲突。
  • 您的查询返回了两条记录,Booking 2 和 Booking 3。但是日期范围 9 月 20 日 - 21 日应该没有冲突吧?
  • 这适用于包容性结束日期,OP 想要独占结束日期,例如如果有人在 9 月 21 日离开,那么这一天应该被认为是可用的。
  • @DerrickMoeller 。 . .这假定结束日期包含在期间中。如果您的规则略有不同,您只需要调整比较。
猜你喜欢
  • 1970-01-01
  • 2012-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-01
  • 2011-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多