采取以下linq查询:
var summary = results.Select(r =>
new
{
TotalPopulation = results.Sum(s => s.Population),
TotalGross = results.Sum(s => s.Gross),
}).Distinct();
以上工作正常,但这是最好的方法。 r代表什么?我为什么需要它?
另外,我认为我可以在查询中添加以下内容,但我不能:
GrossPerPop = TotalPopulation / TotalGross
以上说在当前情况下不存在TotalPopulation和Total Gross。
我也尝试过:
GrossPerPop = results.sum(s => s.Population) / results.Sum(s => s.Gross),
以上说/不能应用于小数?还是加倍?这与可空的字段有什么关系吗?碰巧我没有任何Population字段或具有空值的Gross字段,所以我将这些字段更改为sql表设计器中的非可空字段。但是,如果它们确实包含0值,我怎么能在Linq代码中检查它?
答案 0 :(得分:3)
更好的方法是:
class Metrics {
public int TotalPopulation { get; set; }
public decimal TotalGross { get; set; }
public decimal GrossPerPopulation {
get {
return TotalGross / TotalPopulation;
}
}
}
然后:
var metrics = new Metrics {
TotalPopulation = results.Sum(s => s.Population),
TotalGross = results.Sum(s => s.Gross)
};
您目前所拥有的是为results
的每个元素执行上述投影(尽管是匿名类型),然后抛弃除了一个结果投影之外的所有元素。你可以在不创建显式类型的情况下完成,就像我上面所做的那样,只使用匿名类型,但这很愚蠢。
r
代表什么?
r
表示您定义的匿名方法中的参数名称。
为什么需要它?
写作时
results.Select(expression)
expression
必须是一个委托,它会占用results
元素的任何类型,并返回其他类型。那是IEnumerable<SomeType>.Select
用于将序列投射到另一个序列。因此,您必须传递一个方法,该方法会占用results
元素的任何类型,并返回其他类型。一种方法是通过传递一个匿名委托。定义匿名委托的一种方法是使用lambda表达式。当你说r => ...
时,你正在通过lambda表达式定义一个匿名方法。
另外,我认为我可以在查询中添加以下内容,但我不能:
GrossPerPop = TotalPopulation / TotalGross
没错,你做不到。想想这样。假设您有一个明确的类型
class Metrics {
public int TotalPopulation { get; set; }
public decimal TotalGross { get; set; }
public decimal GrossPerPopulation { get; set; }
public Metrics(
int totalPopulation,
decimal totalGross,
decimal grossPerPopulation
) {
TotalPopulation = totalPopulation;
TotalGross = totalGross;
GrossPerPopulation = grossPerPopulation;
}
}
以下是否合法?
Metrics m = new Metrics(100, 100, m.TotalPopulation / m.TotalGross)
当然不是!但这实际上就是你要做的事情。
GrossPerPop = results.Sum(s => s.Population) / results.Sum(s => s.Gross)
以上说
/
不能应用于小数?还是加倍?
我认为你没有理由得到这样的信息。在C#中,上述内容是合法的,假设s.Population
和s.Gross
都是数字类型;它们只会被隐含地提升为“正确”类型。即使s.Population
或s.Gross
是数字类型,也是如此。
请注意,每人口总数应为
results.Sum(s => s.Gross) / results.Sum(s => s.Population)
答案 1 :(得分:2)
这不是一个好的查询,因为将为每一行计算Sum,然后它将是“不同的”。
只需写下
var summary = new
{
TotalPopulation = results.Sum(s => s.Population),
TotalGross = results.Sum(s => s.Gross),
};