在LINQ中的select语句中执行计算

时间:2016-06-07 19:53:54

标签: c# linq linq-to-sql

我有一种情况,我必须计算两个值的百分比 例如

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语句中描述的那样。

我甚至尝试了这个查询,但我得到的结果是

 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
            });

由于某种原因或另一个期望的教育变量给我0作为结果。

任何帮助表示赞赏。 谢谢

5 个答案:

答案 0 :(得分:6)

为此,请使用LINQ let operator

一般情况下,我建议将几个较小的LINQ语句拆分。否则,稍后调试它将非常痛苦。

答案 1 :(得分:1)

如果您想从原始查询中提取值,然后填充其他属性,可以这样做:

        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
            });

然而,似乎你在个人任务中做了很多“重新查明”相同记录。你可以通过在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()
            });

答案 2 :(得分:1)

那么,假设您想要实际RenewalModel的2个属性之间的比率,为什么不声明每次或首次使用时都进行计算的只读属性?

class RenewalModel
{
    public int desiredCalucation => 
       (PotentialRenewalCount/PotentialRenewalCount)*100;

    // ...
}

顺便说一句,您可能希望使用double并修复公式以使用适当的变量并使用浮点进行计算。

您还应该修改变量名称中的拼写错误。 Calucation拼写不正确!更糟糕的是,这个名字确实说明了该物业的目的。

执行此类属性的一个好处是,如果多个查询返回该信息,它允许代码重用,它会阻止从外部更改值,并且不会影响LINQ代码生成。

但是由于原始代码不起作用,我们没有任何应该做的例子,因此很难猜测它应该做什么。

答案 3 :(得分:1)

Altough我不明白为什么人们会将一个数字单独用于将它乘以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时的情况,因为这会导致除以零!

答案 4 :(得分:0)

当Linq将表达式转换为SQL时,它会在执行查询时将值截断为整数,因此当我使用例如:

select new SomeModel{
    Value = 3/7
}

它返回0.

但是,当我使用时:

select new SomeModel{
    Value = 3.0 / 7.0
}

返回正确的值= 0.428 ...

所以,我认为当你使用Linq To Entities使用的表达式时,必须返回double或decimal,你应该将所有值明确地写为或转换为double ...

我希望它有所帮助。