【问题标题】:How to check existing in DB for any matching Room, BookDate and RoomId?如何检查数据库中是否存在任何匹配的 Room、BookDate 和 RoomId?
【发布时间】:2021-02-14 09:05:34
【问题描述】:

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

TimeSlots 一个集合。我不确定我是否正确地做到了。

这是我的上下文:

var result = await context.Bookings
    .SingleOrDefaultAsync(b => 
        b.BookDate == booking.BookDate 
        && b.TimeSlots == booking.TimeSlots 
        && b.RoomId == booking.RoomId);
public class Booking
{
    public int Id { get; set; }

    [Required]
    public DateTime BookDate { get; set; }

    [Required]
    public int RoomId { get; set; }

    public Room Room { get; set; }

    [Required]
    public ICollection<BookingTimeSlot> TimeSlots { get; set; }

    [Required]
    public ICollection<BookingModule> Modules { get; set; }

    public Booking()
    {
        TimeSlots = new Collection<BookingTimeSlot>();
        Modules = new Collection<BookingModule>();
    }
}
public class BookingTimeSlot
{
    public int BookingId { get; set; }    
    public int TimeSlotId { get; set; }
    public Booking Booking { get; set; }
    public TimeSlot TimeSlot { get; set; }
}

这是我要输入的内容:

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

【问题讨论】:

    标签: c# asp.net asp.net-core asp.net-web-api asp.net-core-webapi


    【解决方案1】:

    您的问题不清楚您是要查找重复项还是要获得第一个结果。

    其次,我认为您缺少 primary key in your model 或者您使用的是复合键,无论哪种方式都可以帮助您解决此问题。

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

    【讨论】:

    • 抱歉错误。我并不是要检查重复项,而是要检查我的输入是否与数据库中的任何记录匹配。
    • 我试过 FirstOrDefaultAsync 但没有运气。它仍在返回null
    • 那就表示没有匹配,只需将其缩减为var result = await context.Bookings .FirstOrDefaultAsync(b =&gt; b.RoomId == booking.RoomId ) 并测试它是否有结果然后添加更多条件。如果有效,请标记为答案
    【解决方案2】:

    嗯,在大多数情况下,数据库中的参照完整性并不能解决此类问题,而且在绝大多数情况下,无论如何都不会使用 RI。原因是这不是 RI 的工作,但更糟糕的是,对于通知用户无法完成此类预订的用户界面而言,此类违反 RI 的行为往往发生得太晚。换句话说,您不要尝试进行预订,保持手指交叉,并希望可以写出数据。

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

    可以根据这个逻辑发现预订冲突:

    RequestStartDate <= EndDate 
    and 
    RequestEndDate >= 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
    

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

    【讨论】:

      【解决方案3】:

      我找到了解决问题的方法。我使用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;
      }
      

      【讨论】:

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