Search code examples
c#asp.net-corerazor-pages

How do I filter a list by another list in a Razor page?


'transactions' contains a list of transaction records...

var transactions = from t in _context.Transaction
                            .Include(t => t.Account)
                            .Include(t => t.Account.AccountOwner)
                            select t;

'SelectedAccountOwners' is a list of strings based on a multiselect box...

[BindProperty(SupportsGet = true)]
public List<string> SelectedAccountOwners { get; set; }

How can I filter 'transactions' so that only records with an Account.AccountOwner.Name in the list of 'SelectedAccountOwners' remain?

Index.cshtml.cs

namespace PersonalFinance_v0._1.Pages.Transactions
{
    public class IndexModel : PageModel
    {
        private readonly PersonalFinance_v0_1.Data.PersonalFinance_v0_1Context _context;

        public IndexModel(PersonalFinance_v0_1.Data.PersonalFinance_v0_1Context context)
        {
            _context = context;
        }

        public IList<Transaction> Transaction { get;set; }

        public IList<Transaction> FilterOutput { get; set; }

        [BindProperty(SupportsGet = true)]
        public List<string> SelectedAccountOwners { get; set; }

        [BindProperty(SupportsGet = true)]
        public string groupNumber { get; set; }

        public async Task OnGetAsync()
        {
            var accountOwnerQuery = from a in _context.AccountOwner
                                    orderby a.Name
                                    select a.Name;

            var accountQuery = from a in _context.Account
                               orderby a.Name
                               select a.Name;

            var transactions = from t in _context.Transaction
                                .Include(t => t.Account)
                                .Include(t => t.Account.AccountOwner)
                               select t;

            if (SelectedAccountOwners.Any())
            {
                Debug.Print("Filter Transactions by Selected Owners");
            }

            if (!string.IsNullOrEmpty(groupNumber))
            {
                transactions = transactions.Where(t =>     t.GroupNumber.Equals(Convert.ToInt32(groupNumber)));
            }

            ViewData["AccountOwners"] = new SelectList(await     accountOwnerQuery.Distinct().ToListAsync());

            ViewData["Accounts"] = new SelectList(await accountQuery.Distinct().ToListAsync());

            Transaction = await transactions
                .OrderBy(t => t.Date).ThenBy(t => t.GroupNumber)
                .ToListAsync();
        }
    }
}

Solution

  • You can use Contains in your Where clause. Something like this:

    if (SelectedAccountOwners.Any())
    {
        transactions = transactions.Where(t => SelectedAccountOwners.Contains(t.Account.AccountOwner.Name));
    }