C# 如何检查数据库中现有的任何匹配房间、预订日期和RoomId?

C# 如何检查数据库中现有的任何匹配房间、预订日期和RoomId?,c#,asp.net,asp.net-core,asp.net-web-api,asp.net-core-webapi,C#,Asp.net,Asp.net Core,Asp.net Web Api,Asp.net Core Webapi,如何检查数据库中是否存在条目?调试显示结果返回null 时隙集合。我不确定我是否做对了 以下是我的背景: var result = await context.Bookings .SingleOrDefaultAsync(b => b.BookDate == booking.BookDate && b.TimeSlots == booking.TimeSlots && b.RoomId == bo

如何检查数据库中是否存在条目?调试显示
结果
返回
null

时隙
集合。我不确定我是否做对了

以下是我的背景:

var result = await context.Bookings
    .SingleOrDefaultAsync(b => 
        b.BookDate == booking.BookDate 
        && b.TimeSlots == booking.TimeSlots 
        && b.RoomId == booking.RoomId);
这是我试图做的输入:

{
    "RoomId": 1,
    "BookDate": "2020-10-27",
    "TimeSlots": [1, 3],
    "Modules": [1]
}

你的问题不清楚你是想找到重复的还是想得到第一个结果

第二,我认为您丢失了,或者您使用的是复合键,无论哪种方式,它都可以帮助您解决这个问题

//With Linq and EF find and process duplicates     
// assuming Id is your primary key - [please fix this, some info for you][1] 
var duplicateBookings = context.Bookings.GroupBy(i => i.id)
                     .Where(x => x.Count() > 1)
                     .Select(val => val.Key); // or .SelectMany(i => i.ToList());
// do what you need
foreach(var dupes in duplicateBookings )
{
    //process or do what you need
    context.Bookings.DeleteObject(dupes); // for e.g. delete duplicate bookings
}
如果您只想要第一个结果,那么将sing更改为first

var result = await context.Bookings
    .FirstOrDefaultAsync(b =>        //first result
        b.BookDate == booking.BookDate 
        && b.TimeSlots == booking.TimeSlots 
        && b.RoomId == booking.RoomId);

你的问题不清楚你是想找到重复的还是想得到第一个结果

第二,我认为您丢失了,或者您使用的是复合键,无论哪种方式,它都可以帮助您解决这个问题

//With Linq and EF find and process duplicates     
// assuming Id is your primary key - [please fix this, some info for you][1] 
var duplicateBookings = context.Bookings.GroupBy(i => i.id)
                     .Where(x => x.Count() > 1)
                     .Select(val => val.Key); // or .SelectMany(i => i.ToList());
// do what you need
foreach(var dupes in duplicateBookings )
{
    //process or do what you need
    context.Bookings.DeleteObject(dupes); // for e.g. delete duplicate bookings
}
如果您只想要第一个结果,那么将sing更改为first

var result = await context.Bookings
    .FirstOrDefaultAsync(b =>        //first result
        b.BookDate == booking.BookDate 
        && b.TimeSlots == booking.TimeSlots 
        && b.RoomId == booking.RoomId);

大多数情况下,数据库中的引用完整性并不能解决这些问题,而且在绝大多数情况下,无论如何都不会使用RI。原因是,这不是RI的工作,但更糟糕的是,对于通知用户此类预订无法完成的用户界面来说,此类违反RI的情况往往发生得太晚。换言之,你不想做预订,祈求好运,希望数据能写出来

您要做的是提供一个用户界面,当用户选择预订日期时,您会给出无法进行预订的反馈,因此不会发生数据库写入或更新-因此这是一个用户界面问题,而不是真正的数据库问题。即使这是一个数据库RI问题,您也必须尝试写入数据,而且用户通常只是检查并询问特定的预订日期,没有必要准备实际预订

可以根据以下逻辑找到预订冲突:

RequestStartDate <= EndDate 
and 
RequestEndDate >= StartDate 
RequestStartDate=StartDate
因此,通过上面的简单查询,可以找到任何重叠,甚至完整的括号

那么,上面是什么?然后使用房间号和该房间的预订日期范围列表,则会发现与以下内容冲突:

@dtRequestStartDate = "Enter start Date" 
@dtRequestEndDate = "Enter end date"
@RoomNum = Room number

strSQL = SELECT * from tblBookings where  
         (@dtRequestStartDate <= RoomEndDate)
         AND
         (@dtRequestEndDate >= RoomStartDate)
         AND
         (@RoomNum = RoomNumber)

 If above row.Count > 0 then 
     message = Sorry, you cannot book that room
@dtRequestStartDate=“输入开始日期”
@dtRequestEndDate=“输入结束日期”
@RoomNum=房间号
strSQL=从tblBookings中选择*,其中
(@dtRequestStartDate=RoomStartDate)
及
(@RoomNum=RoomNumber)
如果上面的行数>0,则
对不起,你不能预订那个房间

所以你要做的是在预订前检查,如果上面返回了行,那么你不允许预订。只要您不允许预订重叠,那么上述简单逻辑将始终有效,并始终防止预订发生冲突。

好吧,数据库中的大部分引用完整性并不能解决此类问题,并且在绝大多数情况下,无论如何都不使用RI。原因是,这不是RI的工作,但更糟糕的是,对于通知用户此类预订无法完成的用户界面来说,此类违反RI的情况往往发生得太晚。换言之,你不想做预订,祈求好运,希望数据能写出来

您要做的是提供一个用户界面,当用户选择预订日期时,您会给出无法进行预订的反馈,因此不会发生数据库写入或更新-因此这是一个用户界面问题,而不是真正的数据库问题。即使这是一个数据库RI问题,您也必须尝试写入数据,而且用户通常只是检查并询问特定的预订日期,没有必要准备实际预订

可以根据以下逻辑找到预订冲突:

RequestStartDate <= EndDate 
and 
RequestEndDate >= StartDate 
RequestStartDate=StartDate
因此,通过上面的简单查询,可以找到任何重叠,甚至完整的括号

那么,上面是什么?然后使用房间号和该房间的预订日期范围列表,则会发现与以下内容冲突:

@dtRequestStartDate = "Enter start Date" 
@dtRequestEndDate = "Enter end date"
@RoomNum = Room number

strSQL = SELECT * from tblBookings where  
         (@dtRequestStartDate <= RoomEndDate)
         AND
         (@dtRequestEndDate >= RoomStartDate)
         AND
         (@RoomNum = RoomNumber)

 If above row.Count > 0 then 
     message = Sorry, you cannot book that room
@dtRequestStartDate=“输入开始日期”
@dtRequestEndDate=“输入结束日期”
@RoomNum=房间号
strSQL=从tblBookings中选择*,其中
(@dtRequestStartDate=RoomStartDate)
及
(@RoomNum=RoomNumber)
如果上面的行数>0,则
对不起,你不能预订那个房间

所以你要做的是在预订前检查,如果上面返回了行,那么你不允许预订。只要您不允许预订重叠,那么上述简单逻辑将始终有效,并始终防止预订发生冲突。

我找到了解决问题的方法。我使用
Intersect
比较TimeSlotId,如果存在交集,则返回true

public bool BookingExist(Booking booking)
{
    var resultContext = context.Bookings
        .Where(b => b.Room.Id == booking.RoomId && b.BookDate == booking.BookDate)
        .SelectMany(b => b.TimeSlots.Select(bt => bt.TimeSlotId))
        .AsEnumerable();

    var resultInput = booking.TimeSlots.Select(bt => bt.TimeSlotId);

    if (resultContext.Intersect(resultInput).Count() > 0)
        return true;
    else
        return false;
}

我已经找到了解决我问题的办法。我使用
Intersect
比较TimeSlotId,如果存在交集,则返回true

public bool BookingExist(Booking booking)
{
    var resultContext = context.Bookings
        .Where(b => b.Room.Id == booking.RoomId && b.BookDate == booking.BookDate)
        .SelectMany(b => b.TimeSlots.Select(bt => bt.TimeSlotId))
        .AsEnumerable();

    var resultInput = booking.TimeSlots.Select(bt => bt.TimeSlotId);

    if (resultContext.Intersect(resultInput).Count() > 0)
        return true;
    else
        return false;
}

对不起,弄错了。我不是要检查重复项,而是要检查我的输入是否与数据库中的任何记录匹配。它仍然返回
null
。那么这意味着没有匹配项,只需将其减少为
var result=wait context.Bookings.FirstOrDefaultAsync(b=>b.RoomId==booking.RoomId)
,如果得到结果,则对其进行测试,然后添加更多条件。如果行得通,请标记为“回答”,为这个错误感到抱歉。我不是要检查重复项,而是要检查我的输入是否与数据库中的任何记录匹配。它仍然返回
null
。那么这意味着没有匹配项,只需将其减少为
var result=wait context.Bookings.FirstOrDefaultAsync(b=>b.RoomId==booking.RoomId)
,如果得到结果,则对其进行测试,然后添加更多条件。如果有效,请标记为答案