2011-03-07 28 views
5

Bir rapor için bazı değerleri hesaplamak için linq sorguları aşağıdaki bloğu var.Neden linq sorgularımdaki değerler hemen görünmüyor?

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; 

Kodda bir hata ayıklayıcıya adım attım ve bazı tuhaflıklar fark ettim. test içine tahsis sonra değeri ExtraSalesExtraSales == 11.31 içine ayarlandıktan sonra test3 içine test == 11.31test2 == 11.28 ve test3 == 22.59 ayrıldıktan sonra test2test2 == 0 ve test == 11.31 içine tahsis sonra 0'dır. Bu işlem tamamlandığında, ExtraSales'daki değer 22.59 olmalıdır. Burada neler oluyor?

DÜZENLEME: ExtraSales içine görevden sonra ek satırlar ekledim ama değer değişmez.

cevap

22

cevapları. Bir operatör önceliği sorunudur.

tamamen alakasız ve orada kod imkansız okuması tüm kurtulun. Hepsi kırmızı ringa balığı. İlgili repro geçerli:

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; 

son satırın anlamı nedir? Bundan önceki çizgi ile aynı anlama geliyor mu?

Hayır, öyle değil. toplama işleci boş kaynaştırma operatörü daha yüksek önceliği, bu nedenle bu d1 boş değilse "demektir yazdı kod d1 değerini üretmek

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

olduğunu. d1 null ve 0 ay + d2 ise boş değil o zaman 0m + d2 değerini üretir. 0 ay + d2 sonra değer 0m üretmek null ise."

(Sen ?? operatörü bu hoş zincirleme özelliğine sahip olduğu bilinmektedir olmayabilirdi. Genelde, a ?? b ?? c ?? d ?? e size a, b, c veya d ve e ilk boş olmayan bir değer verir, aksi takdirde tüm boş olup olmadığını . sürece istediğiniz gibi zincir yapabilirsiniz. oldukça zarif bir küçük operatörü.)

d1 boş olmadığından, biz onun değerini üretmek ve test4 d1 değeri atanır.

Muhtemelen demek istedi:

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

Eğer demek istediğin "d1 veya d2 boş olabilir ve ya ise, o zaman sıfır olarak boş bir tedavi".Yani 12 + 2 12'dir boş 14, 12 + ise, boş + boş yani

var mı demek ise "ya d1 ve d2 boş olabilir ve eğer ikisinden biri sonra sıfır boş istiyorum" 0

olduğunu

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

Yani 12 + 2 0 sıfır 14, 12 + ise, boş + boş 'ı ilgili metin ekranında oldu böylece kodunuzu biçimlendirilmiş olsaydı, muhtemelen gitmeyeceklerini not 0

olduğunu İlk önce beş ya da daha fazla yanlış cevap aldık. Kodunuzu biçimlendirmeye çalışın, böylece hepsi ekranda görünür; yaparsanız daha iyi cevaplar alırsınız.

+0

Bir profesyonel gibi yanıtlandı. –

+0

Biliyorsun, daha iyi bilmeliydim. Geçmişte bu öncelik problemine bir senaryoda rastladım. başka bir operatörden daha yüksek önceliğe sahipti. Hata ayıklayıcı bana yanıltıcı bilgi verdi. – Mykroft

-1

Evet,

1

... o ertelenmiş yürütme denir ve gerçekten güçlü olabilir şeylerden biridir, ama aynı zamanda bunu bekliyoruz değil size çelme Sana "kurban" olduğunu düşünüyorum LINQ içinde ertelenmiş yürütme. kavramını açıklayan bu blog yazısı kontrol edin: Bu ertelenmiş yürütme sorunudur yanlış olduğunu söylemek

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

İlgili konular