The code you've provided doesn't compile because you're trying to assign a sequence of a sequence of strings (each top-level sequence coming from a specific expense) to a reference that expects a sequence of strings.
Going by the return-type of your query, I assume you only need a sequence containing all the debtors for the user? If so, you need to flatten the result sequence.
// implicitly IEnumerable<string>
var debtors = CurrentExpenses.Where(expense => expense.WhoPaid == username)
.Select(expense => expense.WhoOwes)
.SelectMany(debtors => debtors) // flatten sequence
.Distinct();
(you can use a single SelectMany
clause to do the projection and flattening together.)
or, in query syntax:
var debtors = (from expense in CurrentExpenses
where expense.WhoPaid == username
from debtor in expense.WhoOwes
select debtor).Distinct();
If you need to find all expenses paid by the user and their associated debtors, you can stop at the first filter:
// implicitly IEnumerable<Expense>
var expensesPaidByUser = CurrentExpenses.Where(expense => expense.WhoPaid == username);
The debtors associated with each expense are already encapsulated in theExpense
object, so you probably don't need a query more complicated than this; it's already effectively a sequence of a sequence of debtors grouped by expense.
If you do want a separate type to hold an expense and its associated debtors, you can do this with an anonymous type, although I don't see why its necessary in your case:
// implictly IEnumerable<anonymousType>
var debtorsByExpense = CurrentExpenses.Where(expense => expense.WhoPaid == username)
.Select(expense => new { Expense = expense, Debtors = expense.WhoOwes });