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

Myk*_*oft 5 c# linq linq-to-sql

我有以下块的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;
Run Code Online (Sandbox Code Playgroud)

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

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

Eri*_*ert 22

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

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

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;
Run Code Online (Sandbox Code Playgroud)

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

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

decimal test4 = d1 ?? (0m + d2) ?? 0m;
Run Code Online (Sandbox Code Playgroud)

您编写的代码意味着"如果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);
Run Code Online (Sandbox Code Playgroud)

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

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

  decimal test4 = (d1 + d2) ?? 0m;
Run Code Online (Sandbox Code Playgroud)

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

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