LINQ:选择一个系列?

时间:2010-10-10 14:11:54

标签: c# linq

我正在尝试使用LINQ:

IEnumerable<String> debtors = (from expense in CurrentExpenses
                               where expense.WhoPaid == username
                               select expense.WhoOwes.AsEnumerable()).Distinct();

usernameWhoPaid是字符串,WhoOwesICollection<String>

我想要做的是为IEnumerable支付expense的所有欠费的人username获取Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<System.Collections.Generic.IEnumerable<string>>' to 'System.Collections.Generic.IEnumerable<string>'. An explicit conversion exists (are you missing a cast?) 。我不太确定该怎么做。这是编译器错误:

{{1}}

这个的正确语法是什么?

2 个答案:

答案 0 :(得分:8)

您提供的代码无法编译,因为您尝试为分配一系列字符串序列(每个顶级序列来自特定费用)到期望字符串序列的引用。

按照查询的返回类型,我假设您只需要一个包含用户所有债务人的序列?如果是这样,您需要展平结果序列。

// implicitly IEnumerable<string>
var debtors = CurrentExpenses.Where(expense => expense.WhoPaid == username)
                             .Select(expense => expense.WhoOwes)
                             .SelectMany(debtors => debtors) // flatten sequence
                             .Distinct();

(您可以使用单个SelectMany子句进行投影和展平。)

或者,在查询语法中:

var debtors = (from expense in CurrentExpenses
               where expense.WhoPaid == username
               from debtor in expense.WhoOwes
               select debtor).Distinct();

如果您需要查找用户及其相关债务人支付的所有费用,您可以在第一个过滤器处停止:

// implicitly IEnumerable<Expense>
var expensesPaidByUser = CurrentExpenses.Where(expense => expense.WhoPaid == username);

与每项费用相关联的债务人封装在Expense对象中,因此您可能不需要比此更复杂的查询;它已经有效地按费用分组的一系列债务人。

如果你确实想要一个单独的类型来支付费用及其相关的债务人,你可以用匿名类型来做这件事,虽然我不明白为什么在你的情况下这是必要的:

// implictly IEnumerable<anonymousType>
var debtorsByExpense = CurrentExpenses.Where(expense => expense.WhoPaid == username)
                                      .Select(expense => new { Expense = expense, Debtors = expense.WhoOwes });

答案 1 :(得分:2)

使用:

var debtors = ...

而不是

IEnumerable<String> debtors = ...

LINQ表达式的返回类型通常很难为程序员确定。 var关键字告诉编译器自动推断类型,因此您不需要。将鼠标光标悬停在IDE中的var上,看看编译器推断出了什么。