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

时间:2011-03-07 17:36:08

标签: 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;

我已经在调试器中逐步完成了代码,并且我注意到了一些奇怪之处。分配到test后,其值为0.在分配到test3 test2 test2 == 0和{{1}后分配到test == 11.31 test == 11.31test2 == 11.28后分配到test3 == 22.59 ExtraSales后。完成此操作后,ExtraSales == 11.31中的值应为22.59。这是怎么回事?

编辑:我在分配到ExtraSales后添加了其他行,但值没有变化。

3 个答案:

答案 0 :(得分: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;

最后一行是什么意思?它与之前的行是否相同?

不,它没有。加法运算符优先级比空合并运算符高,所以这是

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

你编写的代码意味着“如果d1不为空,则生成d1的值。如果d1为null且0m + d2不为null,则生成0m + d2的值。如果0m + d2为null则生成值0米“。

(您可能不知道??运算符具有这种令人愉快的链接属性。通常,a ?? b ?? c ?? d ?? e为您提供a,b,c或d的第一个非空值,如果它们是e,则为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都可以为空,如果 为空,那么我想要零”,那就是

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

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

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:-1)

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