public async Task <PagedResults <Opening> > GetOpeningsAsync(
            PagingOptions pagingOptions,
            SortOptions <Opening, OpeningEntity> sortOptions,
            SearchOptions <Opening, OpeningEntity> searchOptions,
            CancellationToken ct)
        {
            var rooms = await _context.Rooms.ToArrayAsync();

            var allOpenings = new List <OpeningEntity>();

            foreach (var room in rooms)
            {
                // Generate a sequence of raw opening slots
                var allPossibleOpenings = _dateLogicService.GetAllSlots(
                    DateTimeOffset.UtcNow,
                    _dateLogicService.FurthestPossibleBooking(DateTimeOffset.UtcNow))
                                          .ToArray();

                var conflictedSlots = await GetConflictingSlots(
                    room.Id,
                    allPossibleOpenings.First().StartAt,
                    allPossibleOpenings.Last().EndAt,
                    ct);

                // Remove the slots that have conflicts and project
                var openings = allPossibleOpenings
                               .Except(conflictedSlots, new BookingRangeComparer())
                               .Select(slot => new OpeningEntity
                {
                    RoomId  = room.Id,
                    Rate    = room.Rate,
                    StartAt = slot.StartAt,
                    EndAt   = slot.EndAt
                });

                allOpenings.AddRange(openings);
            }

            var pseudoQuery = allOpenings.AsQueryable();

            pseudoQuery = searchOptions.Apply(pseudoQuery);
            pseudoQuery = sortOptions.Apply(pseudoQuery);

            var size = pseudoQuery.Count();

            var items = pseudoQuery
                        .Skip(pagingOptions.Offset.Value)
                        .Take(pagingOptions.Limit.Value)
                        .ProjectTo <Opening>()
                        .ToArray();

            return(new PagedResults <Opening>
            {
                TotalSize = size,
                Items = items
            });
        }
Exemplo n.º 2
0
        public async Task <PagedResults <Opening> > GetOpeningsAsync(PagingOptions paggingOptions)
        {
            var rooms = await _context.Rooms.ToArrayAsync();

            var allOpenings = new List <Opening>();

            foreach (var room in rooms)
            {
                // Generate a sequence of raw opening slots
                var allPossibleOpenings = _dateLogicService.GetAllSlots(
                    DateTimeOffset.UtcNow,
                    _dateLogicService.FurthestPossibleBooking(DateTimeOffset.UtcNow))
                                          .ToArray();

                if (allPossibleOpenings.Length == 0)
                {
                    continue;
                }

                var conflictedSlots = await GetConflictingSlots(
                    room.Id,
                    allPossibleOpenings.First().StartAt,
                    allPossibleOpenings.Last().EndAt);

                // Remove the slots that have conflicts and project
                var openings = allPossibleOpenings
                               .Except(conflictedSlots, new BookingRangeComparer())
                               .Select(slot => new OpeningEntity
                {
                    RoomId  = room.Id,
                    Rate    = room.Rate,
                    StartAt = slot.StartAt,
                    EndAt   = slot.EndAt
                })
                               .Select(model => _mapper.Map <Opening>(model));

                allOpenings.AddRange(openings);
            }

            var paggedOpenings = allOpenings.Skip(paggingOptions.Offset.Value).Take(paggingOptions.Limit.Value);

            return(new PagedResults <Opening>
            {
                Items = paggedOpenings,
                TotalSize = allOpenings.Count
            });
        }
        public async Task <IEnumerable <Opening> > GetOpeningsAsync(CancellationToken ct)
        {
            var rooms = await _context.Rooms.ToArrayAsync();

            var allOpenings = new List <Opening>();

            foreach (var room in rooms)
            {
                // Generate a sequence of raw opening slots
                var allPossibleOpenings = _dateLogicService.GetAllSlots(
                    DateTimeOffset.UtcNow,
                    _dateLogicService.FurthestPossibleBooking(DateTimeOffset.UtcNow))
                                          .ToArray();

                var conflictedSlots = await GetConflictingSlots(
                    room.Id,
                    allPossibleOpenings.First().StartAt,
                    allPossibleOpenings.Last().EndAt,
                    ct);

                // Remove the slots that have conflicts and project
                var openings = allPossibleOpenings
                               .Except(conflictedSlots, new BookingRangeComparer())
                               .Select(slot => new OpeningEntity
                {
                    RoomId  = room.Id,
                    Rate    = room.Rate,
                    StartAt = slot.StartAt,
                    EndAt   = slot.EndAt
                })
                               .Select(model => Mapper.Map <Opening>(model));

                allOpenings.AddRange(openings);
            }

            return(allOpenings);
        }
Exemplo n.º 4
0
        /// <summary>
        ///
        /// "entity framework translates the linw expression in to sql query, so that it can execuete the whole thing on databse/server , instead of fetching the whole data to client side"
        ///
        /// 'new System.Linq.SystemCore_EnumerableDebugView<RestApi.Models.BookingEntity>(k).Items' threw an exception of type 'System.InvalidOperationException'
        ///
        ///
        ///
        ///     The LINQ expression 'DbSet<BookingEntity>
        /// .LeftJoin(
        ///     outer: DbSet<RoomEntity>,
        ///     inner: b => EF.Property<Nullable<Guid>>(b, "RoomId"),
        ///     outerKeySelector: r => EF.Property<Nullable<Guid>>(r, "Id"),
        ///     innerKeySelector: (o, i) => new TransparentIdentifier<BookingEntity, RoomEntity>(
        ///         Outer = o,
        ///         Inner = i
        ///     ))
        /// .Where(b => b.Inner.Id == __roomid_0 && ___dateLogicService_1.DoesConflict(
        ///     b: b.Outer,
        ///     start: __start_2,
        ///     end: __end_3))' could not be translated. Either rewrite the query in a form that can be translated,
        ///     or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync().
        ///     See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
        ///
        /// The above is failing because it is not supported in .net core 3.0 and above
        ///
        /// </summary>
        /// <param name="roomid"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public async Task <IEnumerable <BookingRange> > GetConflictingSlots(
            Guid roomid,
            DateTimeOffset start,
            DateTimeOffset end)
        {
            //https://docs.microsoft.com/en-us/ef/core/querying/client-eval
            //https://stackoverflow.com/questions/1578778/using-iqueryable-with-linq
            var result = _context.Bookings.Where(b => (b.Room.Id == roomid)).AsEnumerable().Where(b => _dateLogicService.DoesConflict(b, start, end)).SelectMany(existing => _dateLogicService
                                                                                                                                                                 .GetAllSlots(existing.StartAt, existing.EndAt));

            //_dateLogicService.DoesConflict(b, start, end))).Select(x=>x);

            /*var l = k
             *
             * .SelectMany(existing => _dateLogicService
             *   .GetAllSlots(existing.StartAt, existing.EndAt));*/
            //.ToArrayAsync();

            // return await Task.FromResult(l.ToArray());

            return(await Task.FromResult(result.ToArray()));
        }