Pregunta

I have this query that retrieves sales from a bunch of shops, and returns them as a list. On my report request screen, the user can filter by a number of ids - ShopOwnerId, ShopRegionId, ShopTypeCode, etc.

My query is structured to get all sales between selected dates, then filter down depending on the choices. This is obviously highly inefficient. :

private List<Sales> GetFilteredListOfSales(Request reportreq)
{
    ModelContainer ctn = new ModelContainer();
    List<ShopSale> shopsSales = new List<shopsale>();

    // If no filters are selected
    //
    if (reportreq.RegionalId == null && reportreq.OwnerId == null && reportreq.ShopTypeCode == null)
    {
        shopsSales = (from sale in ctn.ShopSales
                    where sale.DateSold >= reportreq.FromDate && sale.DateSold <= reportreq.ToDate
                    select sale).ToList();
    }


    // If the regional ID has a value...
    // 
    if (reportreq.RegionalId.HasValue)
    {
        shopsSales = (from sale in ctn.ShopSales
                  where sale.Shop.Owner.RegionalId == reportreq.RegionalId
                    && sale.DateSold >= reportreq.FromDate && sale.DateSold <= reportreq.ToDate
                  select sale).ToList();
    }

    // If the owner ID has a value...
    // 
    if (reportreq.OwnerId.HasValue)
    {
        shopsSales = (from sale in ctn.ShopSales
                  where sale.Shop.OwnerId == reportreq.OwnerId
                    && sale.DateSold >= reportreq.FromDate && sale.DateSold <= reportreq.ToDate
                  select sale).ToList();
    }

    if (!string.IsNullOrEmpty(reportreq.ShopTypeCode))
    {
        shopsSales = (from sale in ctn.ShopSales
                  where sale.Shop.ShopTypeCode.ToUpper().Contains(reportreq.ShopTypeCode.ToUpper())
                    && sale.DateSold >= reportreq.FromDate && sale.DateSold <= reportreq.ToDate
                  select sale).ToList();
    }



    return shopsSales;
}

You can see, that this method, queries the sales table between certain dates only if no filters have been selected.

What I'm stuck on is, the user could select more than one filter - e.g. they might select a regionId, and a ShopTypeCode, so I don't want to query ctn.ShopSales for each if filter, because if more than one is selcted, it will wipe out the previously retrieved values.

Does anyone have any advice as to how to get around this issue? If more info is needed just ask!

Thanks

¿Fue útil?

Solución

Sure - you don't want to build the query from scratch each time. Just add extra Where calls conditionally:

var query = ctn.ShopSales.Where(sale => sale.DateSold >= reportreq.FromDate 
                                     && sale.DateSold <= reportreq.ToDate);
if (reportreq.OwnerId.HasValue)
{
    query = query.Where(sale => sale.Shop.OwnerId == reportreq.OwnerId);
}
if (!string.IsNullOrEmpty(reportreq.ShopTypeCode))
{
    query = query.Where(sale.Shop.ShopTypeCode.ToUpper()
                            .Contains(reportreq.ShopTypeCode.ToUpper());
}

var shopSales = query.ToList();

Note that the query won't execute until you materialize it in the final line.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top