問題描述
我有以下 linq 查詢塊來計算報告的一些值.
I have the following block of linq queries to calculate some values for a report.
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.賦值給test2
后test2 == 0
和test == 11.31
test == 11.31
test2 == 11.28
和 test3 == 22.59
分配到 ExtraSales
后 test == 11.31
<代碼>ExtraSales == 11.31.當這一切完成時,ExtraSales
中的值應該是 22.59.這是怎么回事?
I've stepped through the code in a debugger and I've noticed some oddities. After assigning into test
its value is 0. After assigning into test2
test2 == 0
and test == 11.31
after assigning into test3 test == 11.31
test2 == 11.28
and test3 == 22.59
after assigning into ExtraSales
ExtraSales == 11.31
. The value in ExtraSales
when this is all complete should be 22.59. What's going on here?
我在分配到 ExtraSales
后添加了額外的行,但值沒有改變.
I've added additional lines after the assignment into ExtraSales
but the value does not change.
推薦答案
說這是一個延遲執行問題的答案是錯誤的. 這是一個運算符優先級問題.
The answers that say that this is a deferred execution problem are wrong. It is an operator precedence problem.
擺脫那里所有完全不相關且無法閱讀的代碼.這都是紅鯡魚.相關的重現是:
Get rid of all that completely irrelevant and impossible-to-read code in there. It is all red herring. The relevant repro is:
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;
最后一行是什么意思?和前面那行意思一樣嗎?
不,它沒有.加法運算符比空合并運算符優先級,所以這是
No, it does not. The addition operator is higher precedence than the null coalescing operator, so this is
decimal test4 = d1 ?? (0m + d2) ?? 0m;
您編寫的代碼表示如果 d1 不為空,則生成 d1 的值.如果 d1 為空且 0m + d2 不為空,則生成 0m + d2 的值.如果 0m + d2 為空,則生成該值0米."
The code you wrote means "produce the value of d1 if d1 is not null. If d1 is null and 0m + d2 is not null then produce the value of 0m + d2. If 0m + d2 is null then produce the value 0m."
(您可能不知道 ?? 運算符具有這種令人愉快的鏈接屬性.通常,a ?? b ?? c ?? d ?? e
為您提供第一個非空值a、b、c 或 d 的值,如果它們都為 null,則 e 的值.您可以根據需要制作鏈.這是一個非常優雅的小運算符.)
(You might not have known that the ?? operator has this pleasant chaining property. In general, a ?? b ?? c ?? d ?? e
gives you the first non-null value of a, b, c or d, and e if they are otherwise all null. You can make the chain as long as you like. It's quite an elegant little operator.)
由于 d1 不為空,所以我們生成它的值并且 test4 被分配了 d1 的值.
Since d1 is not null, we produce its value and test4 is assigned the value of d1.
你可能想說:
decimal test4 = (d1 ?? 0m) + (d2 ?? 0m);
如果您的意思是d1 或 d2 可能為空,如果其中之一為空,則將空值視為零".所以 12 + 2 是 14,12 + null 是 12,null + null 是 0
If you mean "d1 or d2 could be null, and if either is, then treat the null one as zero". So 12 + 2 is 14, 12 + null is 12, null + null is 0
如果您的意思是d1 和 d2 都可以為 null,如果 either 為 null,那么我想要零",那就是
If you mean "either d1 and d2 could be null, and if either is null then I want zero", that's
decimal test4 = (d1 + d2) ?? 0m;
所以 12 + 2 是 14,12 + null 是 0,null + null 是 0
So 12 + 2 is 14, 12 + null is 0, null + null is 0
我注意到,如果您已將代碼格式化為相關文本顯示在屏幕上,您可能不會首先發布五個左右的錯誤答案.嘗試格式化您的代碼,使其全部顯示在屏幕上;如果你這樣做,你會得到更好的答案.
I note that if you had formatted your code so that the relevant text was on the screen, you probably wouldn't have gotten five or so incorrect answers posted first. Try to format your code so that all of it is on the screen; you'll get better answers if you do.
這篇關于為什么我的 linq 查詢中的值不立即出現?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!