是否可以在同一个查询中有两个投影.Select(...)
?
int total = ...;
var sendersInfo = db.Persons
.Select(p => new
{
sentSMS = p.SentSMS.Count(...large expression...),
})
// Calculate percentages
.Select(i => new
{
sentSMS = i.sentSMS,
percentage = i.sentSMS/total * 100
});
上述情况不起作用,因为显然“i.sentSMS”尚未计算,因此使用0(零)代替结果。
我想避免的是这个(下面),做工作,但重复代码“......大表达......”:
int total = ...;
var sendersInfo = db.Persons
.Select(p => new
{
sentSMS = p.SentSMS.Count(...large expression...),
percentage = p.SentSMS.Count(...large expression...) / total * 100
});
除了我的问题(“有可能......”),有没有最好的方法来实现这一目标?我不喜欢uggly代码。此外,我试图在纯Linq到实体(没有linq到对象)
中实现这一点答案 0 :(得分:1)
评论你的评论:
每次都不需要强制浮动 - 只要其中一个操作数是浮点数,另一个操作数被提升,所以结果的类型具有更高的精度(float> int)。
有两个算术运算:
i.sentSMS / total * 100
// (1) (2)
分裂,然后相乘。运算符/
和*
都具有相同的优先级(参见例如this),因此从左侧开始计算表达式,首先计算商(因为除数和除数都是{ {1}},结果也是int
),然后将结果乘以int
(也是100
)。
所以,而不是做
int
足以做到:
(float)i.sentSMS / (float)total * 100
甚至更短:
// ┌─ (float) thanks to casting
// │ ┌─ (int) -> (float) promotion here, making the result of division a (float) too
// │ │ ┌─ then 100 gets promoted in the second step the same way
(float)i.sentSMS / total * 100
// ┌─ (float) literal, because 100 is an (int) literal and 100.0 (or 100d) is a (double) literal
// │ ┌─ (int) -> (float) promotion
// │ │ ┌─ and again
100f * i.sentSMS / total
是100f
的文字(与float
相同,但更整洁):))
在我看来,(float)100
看起来更好,但它是100.0
的字面值,甚至更高的精确度,因此所有double
都会被提升为float
,同时生成结果double
,因此在将double
结果分配给double
变量时会收到编译器警告,导致精度下降。