在 LINQ 中的 select 语句内执行计算
Perform calculation inside select statement in LINQ
我有一种情况,我必须计算两个值的百分比
例如
IEnumerable<RenewalModel> result =
from r in renewalLists
group r by r.CityID into grpCity
select new RenewalModel
{
CityID = grpCity.Key,
City = (from g in grpCity where g.CityID == grpCity.Key select g.City).First().Trim(),
PotentialRenewalCount = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalCount).Sum(),
PotentialRenewalSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalSQRT).Sum(),
desiredCalucation= (PotentialRenewalCount/PotentialRenewalCount)*100,
RENEWALCOUNT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALCOUNT).Sum(),
RENEWALSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALSQRT).Sum()
};
而我的计算应该是这样的
(PotentialRenewalCount/PotentialRenewalCount)*100
正如我在 select 声明中所描述的那样。
我什至尝试过这个查询,但我得到的结果是 0
IEnumerable<RenewalModel> result =
(from r in renewalLists
group r by r.CityID into grpCity
select new RenewalModel
{
CityID = grpCity.Key,
City = (from g in grpCity where g.CityID == grpCity.Key select g.City).First().Trim(),
PotentialRenewalCount = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalCount).Sum(),
PotentialRenewalSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalSQRT).Sum(),
RENEWALCOUNT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALCOUNT).Sum(),
RENEWALSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALSQRT).Sum()
}).select(r => new RenewalModel
{
desiredCalucation = (r.PotentialRenewalCount / r.PotentialRenewalCount) * 100,
CityID = r.CityID,
City = r.City,
PotentialRenewalCount = r.PotentialRenewalCount,
PotentialRenewalSQRT = r.PotentialRenewalSQRT,
RENEWALCOUNT = r.RENEWALCOUNT,
RENEWALSQRT = r.RENEWALSQRT
});
由于某种原因或另一个 desiredCalucation 变量给我的结果是 0。
感谢任何帮助。
谢谢
为此,使用 LINQ let operator。
一般来说,我建议将大的 LINQ 语句拆分成几个小的语句。不然以后调试这个会很痛苦
如果您想从原始查询中提取值,然后填充一个额外的 属性,您可以这样做:
IEnumerable<RenewalModel> result =
(from r in renewalLists
group r by r.CityID into grpCity
select new RenewalModel
{
CityID = grpCity.Key,
City = (from g in grpCity where g.CityID == grpCity.Key select g.City).First().Trim(),
PotentialRenewalCount = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalCount).Sum(),
PotentialRenewalSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalSQRT).Sum(),
RENEWALCOUNT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALCOUNT).Sum(),
RENEWALSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALSQRT).Sum()
}).select(r => new RenewalModel
{
desiredCalucation = (r.PotentialRenewalCount / r.PotentialRenewalCount) * 100,
CityID = r.CityID,
City = r.City,
PotentialRenewalCount = r.PotentialRenewalCount,
PotentialRenewalSQRT = r.PotentialRenewalSQRT,
RENEWALCOUNT = r.RENEWALCOUNT,
RENEWALSQRT = r.RENEWALSQRT
});
虽然您在个人作业中做了很多 "requerying" 相同的记录。您可以通过在 CityID 上使用 "join" 以更简洁的方式完成同样的事情。
请记住,LINQ 还支持子查询:
IEnumerable<RenewalModel> result =
(from g in (
from r in renewalList
join c in cityList on r.CityID equals c.CityID
select new RenewalModel
{
CityID = grpCity.Key,
City = (from g in grpCity where g.CityID == grpCity.Key select g.City).First().Trim(),
PotentialRenewalCount = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalCount).Sum(),
PotentialRenewalSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalSQRT).Sum(),
RENEWALCOUNT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALCOUNT).Sum(),
RENEWALSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALSQRT).Sum()
})
group g by g.CityID into grpCity
select new RenewalModel
{
desiredCalucation = (g.PotentialRenewalCount / g.PotentialRenewalCount) * 100,
CityID = g.CityID,
City = g.City.Trim(),
PotentialRenewalCount = g.PotentialRenewalCount.Sum(),
PotentialRenewalSQRT = g.PotentialRenewalSQRT.Sum(),
RENEWALCOUNT = g.RENEWALCOUNT.Sum(),
RENEWALSQRT = g.RENEWALSQRT.Sum()
});
好吧,假设您想要实际 RenewalModel
的 2 个属性之间的比率,为什么不声明一个只读的 属性,它要么每次都计算,要么在第一次使用时计算?
class RenewalModel
{
public int desiredCalucation =>
(PotentialRenewalCount/PotentialRenewalCount)*100;
// ...
}
顺便说一下,您可能想使用 double
并修改公式以使用适当的变量并使用浮点数进行计算。
您还应该更正变量名中的拼写错误。 Calucation
拼写错误!更糟糕的是,这个名字确实说明了 属性.
的目的
这样做的好处 属性 是它允许代码重用,如果多个查询 return 该信息,它防止从外部更改值并且不会影响 LINQ代码生成。
但是由于原始代码不起作用,而且我们没有任何示例说明它应该做什么,因此很难猜测它应该做什么。
虽然我不明白为什么要将一个数字本身除以乘以 100 - 我相信你正在寻找的东西叫做 let
。现在,我还没有对此进行测试,但它的工作方式应该与此类似:
IEnumerable<RenewalModel> result =
from r in renewalLists
group r by r.CityID into grpCity
let potentialRenewalCount = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalCount).Sum()
let desiredCalculation = (PotentialRenewalCount/PotentialRenewalCount)*100
select new RenewalModel
{
CityID = grpCity.Key,
City = (from g in grpCity where g.CityID == grpCity.Key select g.City).First().Trim(),
PotentialRenewalCount = potentialRenewalCount,
PotentialRenewalSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalSQRT).Sum(),
DesiredCalucation = desiredCalculation,
RENEWALCOUNT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALCOUNT).Sum(),
RENEWALSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALSQRT).Sum()
};
还要考虑 SUM 为 0 的情况,因为这会导致除以零!
当 Linq 将表达式翻译为 SQL 时,它会在执行查询时将值截断为整数,因此当我使用例如:
select new SomeModel{
Value = 3/7
}
它 returns 0.
但是,当我使用时:
select new SomeModel{
Value = 3.0 / 7.0
}
returns 正确值 = 0.428...
因此,我认为当您使用 Linq To Entities 使用的表达式时,必须 return 双精度或十进制,您应该将所有值显式写入或强制转换为双精度...
希望对您有所帮助。
我有一种情况,我必须计算两个值的百分比 例如
IEnumerable<RenewalModel> result =
from r in renewalLists
group r by r.CityID into grpCity
select new RenewalModel
{
CityID = grpCity.Key,
City = (from g in grpCity where g.CityID == grpCity.Key select g.City).First().Trim(),
PotentialRenewalCount = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalCount).Sum(),
PotentialRenewalSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalSQRT).Sum(),
desiredCalucation= (PotentialRenewalCount/PotentialRenewalCount)*100,
RENEWALCOUNT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALCOUNT).Sum(),
RENEWALSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALSQRT).Sum()
};
而我的计算应该是这样的
(PotentialRenewalCount/PotentialRenewalCount)*100
正如我在 select 声明中所描述的那样。
我什至尝试过这个查询,但我得到的结果是 0
IEnumerable<RenewalModel> result =
(from r in renewalLists
group r by r.CityID into grpCity
select new RenewalModel
{
CityID = grpCity.Key,
City = (from g in grpCity where g.CityID == grpCity.Key select g.City).First().Trim(),
PotentialRenewalCount = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalCount).Sum(),
PotentialRenewalSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalSQRT).Sum(),
RENEWALCOUNT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALCOUNT).Sum(),
RENEWALSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALSQRT).Sum()
}).select(r => new RenewalModel
{
desiredCalucation = (r.PotentialRenewalCount / r.PotentialRenewalCount) * 100,
CityID = r.CityID,
City = r.City,
PotentialRenewalCount = r.PotentialRenewalCount,
PotentialRenewalSQRT = r.PotentialRenewalSQRT,
RENEWALCOUNT = r.RENEWALCOUNT,
RENEWALSQRT = r.RENEWALSQRT
});
由于某种原因或另一个 desiredCalucation 变量给我的结果是 0。
感谢任何帮助。 谢谢
为此,使用 LINQ let operator。
一般来说,我建议将大的 LINQ 语句拆分成几个小的语句。不然以后调试这个会很痛苦
如果您想从原始查询中提取值,然后填充一个额外的 属性,您可以这样做:
IEnumerable<RenewalModel> result =
(from r in renewalLists
group r by r.CityID into grpCity
select new RenewalModel
{
CityID = grpCity.Key,
City = (from g in grpCity where g.CityID == grpCity.Key select g.City).First().Trim(),
PotentialRenewalCount = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalCount).Sum(),
PotentialRenewalSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalSQRT).Sum(),
RENEWALCOUNT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALCOUNT).Sum(),
RENEWALSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALSQRT).Sum()
}).select(r => new RenewalModel
{
desiredCalucation = (r.PotentialRenewalCount / r.PotentialRenewalCount) * 100,
CityID = r.CityID,
City = r.City,
PotentialRenewalCount = r.PotentialRenewalCount,
PotentialRenewalSQRT = r.PotentialRenewalSQRT,
RENEWALCOUNT = r.RENEWALCOUNT,
RENEWALSQRT = r.RENEWALSQRT
});
虽然您在个人作业中做了很多 "requerying" 相同的记录。您可以通过在 CityID 上使用 "join" 以更简洁的方式完成同样的事情。
请记住,LINQ 还支持子查询:
IEnumerable<RenewalModel> result =
(from g in (
from r in renewalList
join c in cityList on r.CityID equals c.CityID
select new RenewalModel
{
CityID = grpCity.Key,
City = (from g in grpCity where g.CityID == grpCity.Key select g.City).First().Trim(),
PotentialRenewalCount = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalCount).Sum(),
PotentialRenewalSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalSQRT).Sum(),
RENEWALCOUNT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALCOUNT).Sum(),
RENEWALSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALSQRT).Sum()
})
group g by g.CityID into grpCity
select new RenewalModel
{
desiredCalucation = (g.PotentialRenewalCount / g.PotentialRenewalCount) * 100,
CityID = g.CityID,
City = g.City.Trim(),
PotentialRenewalCount = g.PotentialRenewalCount.Sum(),
PotentialRenewalSQRT = g.PotentialRenewalSQRT.Sum(),
RENEWALCOUNT = g.RENEWALCOUNT.Sum(),
RENEWALSQRT = g.RENEWALSQRT.Sum()
});
好吧,假设您想要实际 RenewalModel
的 2 个属性之间的比率,为什么不声明一个只读的 属性,它要么每次都计算,要么在第一次使用时计算?
class RenewalModel
{
public int desiredCalucation =>
(PotentialRenewalCount/PotentialRenewalCount)*100;
// ...
}
顺便说一下,您可能想使用 double
并修改公式以使用适当的变量并使用浮点数进行计算。
您还应该更正变量名中的拼写错误。 Calucation
拼写错误!更糟糕的是,这个名字确实说明了 属性.
这样做的好处 属性 是它允许代码重用,如果多个查询 return 该信息,它防止从外部更改值并且不会影响 LINQ代码生成。
但是由于原始代码不起作用,而且我们没有任何示例说明它应该做什么,因此很难猜测它应该做什么。
虽然我不明白为什么要将一个数字本身除以乘以 100 - 我相信你正在寻找的东西叫做 let
。现在,我还没有对此进行测试,但它的工作方式应该与此类似:
IEnumerable<RenewalModel> result =
from r in renewalLists
group r by r.CityID into grpCity
let potentialRenewalCount = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalCount).Sum()
let desiredCalculation = (PotentialRenewalCount/PotentialRenewalCount)*100
select new RenewalModel
{
CityID = grpCity.Key,
City = (from g in grpCity where g.CityID == grpCity.Key select g.City).First().Trim(),
PotentialRenewalCount = potentialRenewalCount,
PotentialRenewalSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.PotentialRenewalSQRT).Sum(),
DesiredCalucation = desiredCalculation,
RENEWALCOUNT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALCOUNT).Sum(),
RENEWALSQRT = (from g in grpCity where g.CityID == grpCity.Key select g.RENEWALSQRT).Sum()
};
还要考虑 SUM 为 0 的情况,因为这会导致除以零!
当 Linq 将表达式翻译为 SQL 时,它会在执行查询时将值截断为整数,因此当我使用例如:
select new SomeModel{
Value = 3/7
}
它 returns 0.
但是,当我使用时:
select new SomeModel{
Value = 3.0 / 7.0
}
returns 正确值 = 0.428...
因此,我认为当您使用 Linq To Entities 使用的表达式时,必须 return 双精度或十进制,您应该将所有值显式写入或强制转换为双精度...
希望对您有所帮助。