Home > Mobile >  C# web api data filtration
C# web api data filtration

Time:11-22

Good day, I am doing Web api rest project and want to include product search for products by size and color, but I want to be able search for example: 1 One size

[httpGet][Route("oneSize/{sizeID}")]

2 Two Sizes

[httpGet][Route("TwoSizes/{sizeID1}/{sizeID2}")]

3 One size/ One color

[httpGet][Route("OneSizeOneColor/{sizeID1}/{ColorID}")]

4 Two sizes/ One color

[httpGet][Route("TwoSizeOneColor/{sizeID1}/{sizeID2}/{ColorID}")]

etc. Do I need to create end point for every tipe of search or is there a smarter way of doing it?

CodePudding user response:

You should use the query params. You can add them via FromQuery attribute:

[HttpGet]
public IActionResult SearchProducts([FromQuery] int[] sizeIds, [FromQuery] int[] colorIds) {
}

You can replace int with string if you have string Ids.

For example, if you want to make a request with sizes 1 and 2, and color 3 and 4, the request would look like this: https://localhost:5001/your-endpoint-name?sizeIds=1&sizeIds=2&colorIds=3&colorIds=4

So query is a list of key=value url parameters after the ? separated by & sign

EDIT

You can easily query the database with the sql IN operator.

In EF Core, it would look something like this:

IQuaryable<Product> query = dbContext.Products;
if (sizeIds.Length > 0) {
    query= query.Where(p => sizeIds.Contains(p.SizeId));
}
if (colorIds.Length > 0) {
    query= query.Where(p => colorIds.Contains(p.ColorId));
}
List<Product> result = await query.ToListAsync();

It would be translated to the following SQL:

SELECT * FROM Products
WHERE Products.SizeId IN (1, 2) AND Products.ColorId IN (3, 4);

CodePudding user response:

The problem is that I have nested classess

 public class ProductBase
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public ICollection<ProductVariant> Variants { get; set; } = new List<ProductVariant>();
    public int BaseImageId { get; set; } = 0;
    public string BaseImagePath { get; set; } = string.Empty;

}

 public class ProductVariant
{
    public int Id { get; set; }
    public int Quantity { get; set; }
    public int ProductBaseId { get; set; }
    public int ProductSizeId { get; set; }
    public ProductSize ProductSize { get; set; }
    public int ProductColorId { get; set; }
    public ProductColor ProductColor { get; set; }

    public IEnumerable<ImageVariant> imageVariants { get; set; } = new List<ImageVariant>();
}
public class ProductSize
{
    public int Id { get; set; }
    public string Size { get; set; }
}
public class ProductColor
{
    public int Id { get; set; }
    public string Color { get; set; }
}

I am trying something like this

public async Task<IQueryable<Models.ProductBase>> SearchProducts(int[] SizeIds, int[]  ColorIds )
    {
        IQueryable<Models.ProductBase> query = _dataContext.ProductBases
            .Include(pb => pb.Variants).ThenInclude(v => v.ProductSize)
            .Include(pb => pb.Variants).ThenInclude(v => v.ProductColor)
            .Include(pb => pb.Variants).ThenInclude(v => v.imageVariants);
           
        if(SizeIds.Length > 0)
        {
            query = query.Where(pb => SizeIds.Contains(pb.Variants.Any(pb.Variants.doesnotWork));
        }
        if(ColorIds.Length > 0)
        {
            query = query.Where(pb => ColorIds.Contains(pb.Variants.Contains(pb.Variants.doesNotWork)));
        }

        List<ProductBase> result = await query.ToListAsync(); 
    }

CodePudding user response:

Fixed , this is working now

 public async Task<IEnumerable<Models.ProductBase>> SearchProducts(int[] SizeIds, int[]  ColorIds )
    {
        IQueryable<Models.ProductBase> query = _dataContext.ProductBases
            .Include(pb => pb.Variants).ThenInclude(v => v.ProductSize)
            .Include(pb => pb.Variants).ThenInclude(v => v.ProductColor)
            .Include(pb => pb.Variants).ThenInclude(v => v.imageVariants);
           
        if(SizeIds.Length > 0)
        {
            query = query.Where(pb => pb.Variants.ToList().Any(v => SizeIds.Contains(v.ProductSizeId)));
        }
        if(ColorIds.Length > 0)
        {
            query = query.Where(pb => pb.Variants.ToList().Any(v => ColorIds.Contains(v.ProductColorId)));
        }

        List<Models.ProductBase> result = await query.ToListAsync();

        return result;
    }
  • Related