查找 LINQ 日期之间的可用房间
Find available rooms between dates LINQ
我正在尝试制作一个系统,用户可以在其中输入到达日期和离开日期以及他们希望拥有的房间类型,然后程序将检查是否有任何该类型的房间可用,如果有的话将 return 房间号。
这是我用来从视图中检索信息的视图模型
public class AvailabilityDTO
{
[Key]
public string Id { get; set; }
[Required]
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime Arrival { get; set; }
[Required]
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime Departure { get; set; }
[Required]
public string RoomType { get; set; }
}
这是我的数据库表
问题是我不确定如何使用 LINQ 表达式来获取与所述房间类型相同但在选定日期内不属于任何预订的房间的房间号。
我最接近的是使用我在创建预订时使用的相同 LINQ 表达式来检查它是否在管理员 CRUD 中的那些日期被占用。
该表达式是:
private bool OccupiedRoom(Reservation CurrentReservation)
{
var currentBooking = db.Reservations
.Where(b => b.RoomId == CurrentReservation.RoomId)
.Select(b => (b.Arrival <= CurrentReservation.Arrival && b.Depature >= CurrentReservation.Arrival) ||
(b.Arrival < CurrentReservation.Depature && b.Depature >= CurrentReservation.Depature) ||
(CurrentReservation.Arrival <= b.Arrival && CurrentReservation.Depature >= b.Arrival)
)
.FirstOrDefault();
return currentBooking;
}
然而,试图修改它以适应我的情况让我完全难住了,任何帮助都是正确的。
首先,您应该始终从您所追求的实体开始,即 db.Rooms
而不是 db.Reservations
。然后,如果您在 Room
上还没有 Reservations
导航 属性,您应该添加一个,因为它会大大简化查询。这样,确保与房间相关的所有预订要么在请求到达日期之前结束,要么在请求离开日期之后开始就变得很简单了。因此:
var availableRooms = db.Rooms.Where(m => m.Reservations.All(r => r.Departure <= model.Arrival || r.Arrival >= model.Departure)
我在这里使用了 <=
和 >=
,因为在正常情况下,您会在上午 11 点左右退房,然后在下午 3 点左右入住。因此,同一间房间实际上可以由两个人在同一天预订,只要一个人正在退房,另一个人正在入住。如果不是您的情况,请相应地调整查询。
如果您使用的是查询表达式语法,这可能会提供一些想法:
var query = from room in database.Rooms
join res in database.Reservations
on room.roomId equals res.roomId
where room.Type==CurrentReservation.RoomType
&& res.departdate<=CurrentReservation.Dep && res.arrivalDate>=arrDate
select new { Id = res.RoomId };
我正在尝试制作一个系统,用户可以在其中输入到达日期和离开日期以及他们希望拥有的房间类型,然后程序将检查是否有任何该类型的房间可用,如果有的话将 return 房间号。
这是我用来从视图中检索信息的视图模型
public class AvailabilityDTO
{
[Key]
public string Id { get; set; }
[Required]
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime Arrival { get; set; }
[Required]
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime Departure { get; set; }
[Required]
public string RoomType { get; set; }
}
这是我的数据库表
问题是我不确定如何使用 LINQ 表达式来获取与所述房间类型相同但在选定日期内不属于任何预订的房间的房间号。
我最接近的是使用我在创建预订时使用的相同 LINQ 表达式来检查它是否在管理员 CRUD 中的那些日期被占用。 该表达式是:
private bool OccupiedRoom(Reservation CurrentReservation)
{
var currentBooking = db.Reservations
.Where(b => b.RoomId == CurrentReservation.RoomId)
.Select(b => (b.Arrival <= CurrentReservation.Arrival && b.Depature >= CurrentReservation.Arrival) ||
(b.Arrival < CurrentReservation.Depature && b.Depature >= CurrentReservation.Depature) ||
(CurrentReservation.Arrival <= b.Arrival && CurrentReservation.Depature >= b.Arrival)
)
.FirstOrDefault();
return currentBooking;
}
然而,试图修改它以适应我的情况让我完全难住了,任何帮助都是正确的。
首先,您应该始终从您所追求的实体开始,即 db.Rooms
而不是 db.Reservations
。然后,如果您在 Room
上还没有 Reservations
导航 属性,您应该添加一个,因为它会大大简化查询。这样,确保与房间相关的所有预订要么在请求到达日期之前结束,要么在请求离开日期之后开始就变得很简单了。因此:
var availableRooms = db.Rooms.Where(m => m.Reservations.All(r => r.Departure <= model.Arrival || r.Arrival >= model.Departure)
我在这里使用了 <=
和 >=
,因为在正常情况下,您会在上午 11 点左右退房,然后在下午 3 点左右入住。因此,同一间房间实际上可以由两个人在同一天预订,只要一个人正在退房,另一个人正在入住。如果不是您的情况,请相应地调整查询。
如果您使用的是查询表达式语法,这可能会提供一些想法:
var query = from room in database.Rooms
join res in database.Reservations
on room.roomId equals res.roomId
where room.Type==CurrentReservation.RoomType
&& res.departdate<=CurrentReservation.Dep && res.arrivalDate>=arrDate
select new { Id = res.RoomId };