Aleksej_Shherbak
Aleksej_Shherbak

Reputation: 3058

How I can filter IQueryable?

I have the following controller:

public class EventsController : Controller
{
    private readonly ICustomerEventRepository _customerEventRepository;

    public EventsController(ICustomerEventRepository customerEventRepository)
    {
        _customerEventRepository = customerEventRepository;
    }

    public IActionResult Index(int? customerid, int? pageNumber, string code = "")
    {
        IQueryable<CustomerEvent> customerEvents;

        if (customerid.HasValue)
        {
            customerEvents =
                _customerEventRepository.CustomerEvents.Where(x => x.Customer.CustomerId == customerid)
                    .Include(x => x.Customer).OrderByDescending(x => x.CustomerEventId);
        }
        else if (!string.IsNullOrEmpty(code))
        {
            customerEvents =
                _customerEventRepository.CustomerEvents.Where(x => x.EventType == code)
                    .Include(x => x.Customer).OrderByDescending(x => x.CustomerEventId);
        }
        else
        {
            customerEvents = _customerEventRepository.CustomerEvents
                .Include(x => x.Customer).OrderByDescending(x => x.CustomerEventId);
        }

        var page = pageNumber ?? 1;

        var onePageOfEvents = customerEvents.ToPagedList(page, 15);

        return View(onePageOfEvents);
    }
}

Note that

_customerEventRepository = customerEventRepository;

is my repository. It returns IQueryable form my. In the signature of the method Index I have a set of parameters. It's query parameters for filtering. Right now I have 2 (pageNumber is not filter parameter, it's for pagination), but I'm planning more. So this code is not very optimal. If I have more filter parameters I will be forced to make more and more if instructions. Because conditions don't work for LINQ. Maybe somebody had the same issue? I appreciate any help.

Upvotes: 1

Views: 1385

Answers (1)

haldo
haldo

Reputation: 16701

If I have understood you correctly, you want to build up the query based on multiple conditions.

IQueryable defers execution until the collection is materialised (for example calling ToList or iterating over the collection).

This allows you to build up the query piece by piece. See an example below.

IQueryable<CustomerEvent> customerEvents = _customerEventRepository
                                               .CustomerEvents
                                               .Include(x => x.Customer);

if (customerid.HasValue)
{
    customerEvents = customerEvents.Where(x => x.Customer.CustomerId == customerid);
}

if (!string.IsNullOrEmpty(code))
{
    customerEvents = customerEvents.Where(x => x.EventType == code); 
}
// other conditions
...

// finally (this is when the query is actually executed)
var onePageOfEvents = customerEvents
                         .OrderByDescending(x => x.CustomerEventId)
                         .ToPagedList(page, 15);

return View(onePageOfEvents);

Upvotes: 2

Related Questions