为什么我的linq查询中的值不会立即出现?

我有以下块的linq查询来计算报告的某些值。

var items = (from trans in calclabordb.Sales_Transactions select trans).SelectMany(st => st.Sales_TransactionLineItems).Where(stli => stli.TypeID == typeID); decimal test = items.Where(stli => stli.Inventory_Item is Base).Sum(stli => (decimal?)stli.Inventory_Item.IntExtraServiceAmount) ?? 0; decimal test2 = items.Where(stli => stli.Inventory_Item is Extra).Sum(stli => (decimal?)stli.ItemPrice) ?? 0; decimal test3 = test + test2; current.ExtraSales = items.Where(stli => stli.Inventory_Item is Base).Sum(stli => (decimal?)stli.Inventory_Item.IntExtraServiceAmount) ?? 0 + items.Where(stli => stli.Inventory_Item is Extra).Sum(stli => (decimal?)stli.ItemPrice) ?? 0; 

我在调试器中逐步完成了代码,我注意到了一些奇怪之处。 在分配到test其值为0.在分配到test3 test == 11.31 test2 == 11.28test3 == 22.59之后分配到test2 test2 == 0test == 11.31之后分配到ExtraSales ExtraSales == 11.31 。 完成此操作后, ExtraSales的值应为22.59。 这里发生了什么?

编辑:我在分配到ExtraSales后添加了额外的行,但值没有改变。

说这是延迟执行问题的答案是错误的。 这是一个运算符优先级问题。

摆脱那里完全不相关和不可读的代码。 这都是红鲱鱼。 相关的责任是:

 decimal? d1 = 11.31m; decimal? d2 = 11.28m; decimal test1 = d1 ?? 0m; decimal test2 = d2 ?? 0m; decimal test3 = test1 + test2; decimal test4 = d1 ?? 0m + d2 ?? 0m; 

最后一行是什么意思? 它和它之前的线是否意味着相同的东西?

不,不是的。 加法运算符的优先级高于空合并运算符,所以这是

 decimal test4 = d1 ?? (0m + d2) ?? 0m; 

您编写的代码表示“如果d1不为空,则生成d1的值。如果d1为null且0m + d2不为null,则生成0m + d2的值。如果0m + d2为null,则生成值0m。”

(您可能不知道??运算符具有这种令人愉快的链接属性。通常, a ?? b ?? c ?? d ?? e为您提供a,b,c或d的第一个非空值,如果它们全部为空,则为e。你可以根据自己的喜好制作链条。这是一个非常优雅的小操作员。)

由于d1不为null,我们生成其值,test4被赋值为d1。

你可能想说:

 decimal test4 = (d1 ?? 0m) + (d2 ?? 0m); 

如果你的意思是“d1或d2可以为null,如果是,则将null值视为零”。 所以12 + 2是14,12 + null是12,null + null是0

如果你的意思是“d1和d2都可以为null,如果其中任何一个为null,那么我想要零”,那就是

  decimal test4 = (d1 + d2) ?? 0m; 

所以12 + 2是14,12 + null是0,null + null是0

我注意到,如果您已经格式化了代码以便相关文本出现在屏幕上,那么您可能不会首先获得五个左右的错误答案。 尝试格式化代码,以便所有代码都在屏幕上; 如果你这样做,你会得到更好的答案。

我认为你是LINQ中延迟执行的“受害者”。 看看这篇解释这个概念的博文:

http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx

是的,它被称为延迟执行,它是可以真正强大的东西之一,但如果你不期待它也会绊倒你……