public async Task <IHttpActionResult> GetItemsByCategory(
            ItemsPagination pagination,
            [ModelBinder(typeof(ItemCategoryBinder))] string category,
            CancellationToken cancellationToken = default)
        {
            var baseQuery = from i in db.Items.AsNoTracking()
                            select i;

            switch (category)
            {
            case "armor": baseQuery = baseQuery.Where(i => i.IsArmor); break;

            case "consumable": baseQuery = baseQuery.Where(i => i.Consumable); break;

            case "feet": baseQuery = baseQuery.Where(i => i.Slot == "feet"); break;

            case "food": baseQuery = baseQuery.Where(i => i.IsFood); break;

            case "head": baseQuery = baseQuery.Where(i => i.Slot == "head"); break;

            case "rings": baseQuery = baseQuery.Where(i => i.Slot == "ring"); break;

            case "scrolls": baseQuery = baseQuery.Where(i => i.IsScroll); break;

            case "spells": baseQuery = baseQuery.Where(i => i.IsSpell); break;

            case "torches": baseQuery = baseQuery.Where(i => i.IsTorch); break;

            case "weapons": baseQuery = baseQuery.Where(i => i.IsWeapon); break;
            }

            var content = await GetItemsAsync(pagination, baseQuery, cancellationToken);

            return(Ok(content));
        }
        private async Task <ItemsEnvelope> GetItemsAsync(
            ItemsPagination pagination,
            IQueryable <Item> baseQuery,
            CancellationToken cancellationToken)
        {
            var query = from i in baseQuery
                        orderby i.Name
                        select i;

            var total = await query.CountAsync(cancellationToken);

            var items = await(from i in query
                              select new ItemDTO
            {
                Name        = i.Name,
                DisplayName = i.DisplayName,
                Slot        = i.Slot,
                Cost        = i.CoinCost,
                Unlock      = i.DiamondCost,
            })
                        .Page(pagination)
                        .ToListAsync(cancellationToken);

            return(new ItemsEnvelope
            {
                Total = total,
                Items = items,
            });
        }
        public async Task <IHttpActionResult> GetItems(
            ItemsPagination pagination,
            CancellationToken cancellationToken = default)
        {
            var baseQuery = from i in db.Items.AsNoTracking()
                            select i;

            var content = await GetItemsAsync(pagination, baseQuery, cancellationToken);

            return(Ok(content));
        }
        public async Task <IHttpActionResult> GetItemsBySubcategory(
            ItemsPagination pagination,
            ItemSubcategoryFilter filter,
            CancellationToken cancellationToken = default)
        {
            var baseQuery = from i in db.Items.AsNoTracking()
                            select i;

            switch (filter.Category)
            {
            case "weapons":
                switch (filter.Subcategory)
                {
                case "bows": baseQuery = baseQuery.Where(w => w.IsBow); break;

                case "broadswords": baseQuery = baseQuery.Where(w => w.IsBroadsword); break;

                case "cats": baseQuery = baseQuery.Where(w => w.IsCat); break;

                case "crossbows": baseQuery = baseQuery.Where(w => w.IsCrossbow); break;

                case "daggers": baseQuery = baseQuery.Where(w => w.IsDagger); break;

                case "flails": baseQuery = baseQuery.Where(w => w.IsFlail); break;

                case "longswords": baseQuery = baseQuery.Where(w => w.IsLongsword); break;

                case "rapiers": baseQuery = baseQuery.Where(w => w.IsRapier); break;

                case "spears": baseQuery = baseQuery.Where(w => w.IsSpear); break;

                case "whips": baseQuery = baseQuery.Where(w => w.IsWhip); break;
                }
                break;

            case "chest":
                switch (filter.Subcategory)
                {
                case "red": baseQuery = baseQuery.Where(i => (i.IsFood || i.IsTorch || i.IsShovel || RedChestSlots.Contains(i.Slot)) && !i.IsScroll); break;

                case "purple": baseQuery = baseQuery.Where(i => i.IsSpell || i.IsScroll || PurpleChestSlots.Contains(i.Slot)); break;

                case "black": baseQuery = baseQuery.Where(i => i.IsArmor || i.IsWeapon || BlackChestSlots.Contains(i.Slot)); break;

                case "mimic": break;         // All items
                }
                break;
            }

            var content = await GetItemsAsync(pagination, baseQuery, cancellationToken);

            return(Ok(content));
        }