【问题标题】:Issue performing calculations on grouped LINQ query outputting IEnumerable<decimal> and IEnumerable<decimal?> figures对输出 IEnumerable<decimal> 和 IEnumerable<decimal?> 数字的分组 LINQ 查询执行计算时出现问题
【发布时间】:2014-08-31 20:24:29
【问题描述】:

大家好,感谢您阅读/回答(如果您这样做了):

我在尝试获取跨多种货币的每笔交易的平均值时遇到了一些问题。在下面的代码 sn-ps 中,为了简单起见,我将其限制为港币。

我从这个开始:

var avgYieldPerTran = (from fixYield in Total
                   group fixYield by fixYield.trans_id into set
                   select new { 
                         PnL = set.Select(s => s.p_and_l), 
                         exHK = set.Select(s => s.exchange_rate_hkd), 
                         size = set.Select(s => s.size)
                   }).ToList();

decimal avgYieldPTHKD = 0;

foreach(var test in avgYieldPerTran)
                {
              avgYieldPTHKD += (((test.PnL / test.exHK) / (test.size / test.exHK)) * 100);
                }

PnL 和 exHK 是可以为空的小数,size 只是小数。

上面的代码给了我以下 test.PnL / test.exHK 的编译问题:

Operator '/' cannot be applied to operands of type <decimal?> and <decimal?>

还有 test.size / test.exHK 这个问题:

Operator '/' cannot be applied to operands of type <decimal> and <decimal?>

我试图通过以下方式转换为十进制来解决这个问题:

avgYieldPBHKD += (((Convert.ToDecimal(test.PnL) / Convert.ToDecimal(test.exHK)) / (Convert.ToDecimal(test.size) / Convert.ToDecimal(test.exHK))) * 100);

但是,这反过来又给了我一个运行时问题:

Unable to cast object of type 'WhereSelectEnumerableIterator'2[AutomatedTesting.transation, System.Nullable'1[System.Decimal]]' to type 'System.IConvertible'.

然后我想将最终结果四舍五入到小数点后 2 位,但我希望这是我能在孤独中找到的东西。

非常感谢为获得平均数而尝试解决我的类型转换问题的任何和所有帮助。

亲切的问候。

edit 更改了问题标题,因为我觉得和值是IEnumerable&lt;decimal&gt; and IEnumerable&lt;decimal?&gt; 的事实可能很重要......

编辑 - 回答 在 Pragmateek 的协助下回答如下:

var avgYieldPerTran = (from fixYield in Total
                   group fixYield by fixYield.trans_id into set
                   select new { 
                         PnL = set.Sum(s => s.p_and_l), 
                         exHK = set.Average(s => s.exchange_rate_hkd), 
                         size = set.Sum(s => s.size)
                   }).ToList();

decimal avgYieldPTHKD = 0;

foreach(var test in avgYieldPerTran)
                {
              avgYieldPTHKD += (decimal)(((test.PnL / test.exHK) / (test.size / test.exHK)) * 100);
                }

【问题讨论】:

  • 您是否尝试过使用(myNullabe).Value?确保没有 null 值。
  • 如果这不是 Linq->SQL 或 EF Linq 语句(即它完全在内存中),那么我会退回到使用循环而不是迭代器。我不知道为什么你会得到你现在的结果,但如果你真的被卡住并且有紧迫的截止日期,那就放弃使用 Linq 吧。
  • 它是 Linq->EF(我以为我为它贴了一个标签,我很傻)但它不是来自内存,“Total”项目是以前的 LINQ 查询 - 或 2 - 减少为在到达这一点之前尽可能多地过滤掉的东西,而不需要复杂的 group by 子查询。我会将 myNullage.Value 放在哪里?反对 exHK 和 PnL 对象?

标签: c# sql linq entity-framework type-conversion


【解决方案1】:

问题是Select 返回IEnumerables 并且没有/ 运算符。

你可能想要这样的东西:

var avgYieldPerTran = (from fixYield in Total
               group fixYield by fixYield.trans_id into set
               select new { 
                     PnL = set.Average(s => s.p_and_l), 
                     exHK = set.Average(s => s.exchange_rate_hkd), 
                     size = set.Average(s => s.size)
               }).ToList();

然后您将获得带有scalar properties 的对象列表,而不是带有collections properties 的对象列表。

【讨论】:

  • 我用 .Sum() 表示 p_and_l & size,用 .Average() 表示 exchange_rate;原因是如果返回多个结果,我想要平均汇率,但我想要总 PnL 或交易规模。但是,它现在与我的预期答案相差约 2000%。可能不得不重新考虑我的数学方法,但我将其标记为答案,因为它解决了这个问题。谢谢你。毫无价值,我必须通过将(十进制)放在它前面来隐式转换计算。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多