2013-03-08 30 views
18

KODU:değer türü 'Çift' için döküm başarısız

double cafeSales = db.InvoiceLines 
    .Where(x => 
     x.UserId == user.UserId && 
     x.DateCharged >= dateStart && 
     x.DateCharged <= dateEnd) 
    .Sum(x => x.Quantity * x.Price); 

HATA:

değer türü 'Çift' için döküm başarısız hayata değer çünkü boş. Sonuç türünün genel parametresi veya sorguda null bir tür kullanılmalıdır.

Ben ZATEN GÖRDÜĞÜM NE:

The cast to value type 'Int32' failed because the materialized value is null

The cast to value type 'Decimal' failed because the materialized value is null

ne denedim:

double cafeSales = db.InvoiceLines 
    .Where(x => 
     x.UserId == user.UserId && 
     x.DateCharged >= dateStart && 
     x.DateCharged <= dateEnd) 
    .DefaultIfEmpty() 
    .Sum(x => x.Quantity * x.Price); 

Ve:

double? cafeSales = db.InvoiceLines 
    .Where(x => 
     x.UserId == user.UserId && 
     x.DateCharged >= dateStart && 
     x.DateCharged <= dateEnd) 
    .Sum(x => x.Quantity * x.Price); 

bu işin ne. Sorunun nedeninin, bu tablo içinde geçirdiğim UserId için hiçbir satır bulunmadığını biliyorum. Bu durumda, Sum() 'ı yalnızca 0'a döndürmeyi tercih ederim. Herhangi bir fikir? Toplama herhangi doğru sonuçları varsa

+1

En uygun ve verimli olan aşağıdaki çözümlerden yanıt olarak işaretlemelisiniz. –

+2

Başkalarına güvenmek için aşağıdan bir cevap kabul etmelisiniz. –

+1

Olası çoğaltılabilir [Döndürülecek değer türü 'Int32' başarısız oldu, çünkü maddi değeri sıfırdır] (http://stackoverflow.com/questions/6864311/the-cast-to-value-type-int32-failed-because- -maddileştirilmiş değer-null) –

cevap

7

kontrol edebilirsiniz. Bu biraz eski olduğunu biliyoruz

var cafeSales = db.InvoiceLines 
    .Where(x => 
     x.UserId == user.UserId && 
     x.DateCharged >= dateStart && 
     x.DateCharged <= dateEnd && 
     x.Quantity != null && 
     x.Price != null); 

double cafeSalesTotal = 0; 

if (cafeSales.Any()) 
{ 
    cafeSalesTotal = cafeSales.Sum(x => x.Quantity * x.Price); 
} 
+0

Şimdi kendime benzer bir şey buldum, ama bunu yapmanın daha temiz bir yolu olacağını umuyordum .. tek bir açıklamada. – Matt

+0

Size +1 verseniz – Matt

+1

Bu yaklaşımdaki problem, herhangi bir kayıt olup olmadığını ve ardından gerçek toplamı() yapmak için ikinci kaydın olup olmadığını görmek için önce Any() için db'ye 2 sorgunun gönderilmesidir. –

0
var cafeSales = db.InvoiceLines 
.Where(x => 
    x.UserId == user.UserId && 
    x.DateCharged >= dateStart && 
    x.DateCharged <= dateEnd) 
.Sum(x => x.Quantity * x.Price); 

double i; 
if(cafeSales==null) ? i=0 : i=(double)cafeSales.First(); 
+1

Toplam (...) bir numara döndürmeyecek, bu nedenle bir Toplam() 'in bir Sum (...) sonucundan çağrılması bir derleme zamanı hatasına dönüşecektir. – Maarten

+0

İyi yakalama, can sıkıcı bir şekilde First() – James

+0

'u eklemek için düzenledim, herhangi bir anlam ifade ediyor mu? : o eğer (cafeSales == null)? i = 0: i = (çift) cafeSales.First(); –

3

Bu hile yapmak gerekir (ya Quantity veya Price null değilse koşullardan birini kaldırmak gerekebilir) Sadece durumda kimse yardımcı olur.

@Matt DefaultIFEmpty() yönteminin, Sum üzerine uyguladığınız sütun için varsayılan değeri iletmeniz durumunda sizin için çalışması gerektiğini düşünüyorum. Bu yöntemde, kontrol etmek isteyebileceğiniz bazı aşırı yüklenmeler var ve aşırı yükler gereksinimi desteklemiyorsa, tip dökümü öneririm.

(query).DefaultIfEmpty(0) 
4

ama:

double? cafeSales = null; 
var invoices = db.InvoiceLines 
    .Where(x => 
     x.UserId == user.UserId && 
     x.DateCharged >= dateStart && 
     x.DateCharged <= dateEnd 
    ) 
    .Where(x => x.Quantity != null && x.Price != null); 
if (invoices.Any()) { 
    cafeSales = invoices.Sum(x => x.Quantity * x.Price); 
} 
+0

Bana yardımcı oldu. Bu gitmek için harika bir yol. – Meryovi

+0

Sadece bir sorgusu db'ye yardımcı olur ve gönderir, ÇOK Çirkin olanı! DefaultIfEmpty olmadan, basit bir SELECT ifadesidir, DefaultIfEmpty ile oluşturulan sorguda 4 SELECT kullanılır. Herhangi bir istek varsa, db'yi kontrol etmek yerine, sorgu herhangi bir kayıt döndürdüğünde test etmek için C# istemcisindeki sınamanın mümkün olması gerekir. –

46

İyi Çözüm

double cafeSales = db.InvoiceLines 
        .Where(x => 
           x.UserId == user.UserId && 
           x.DateCharged >= dateStart && 
           x.DateCharged <= dateEnd) 
        .Sum(x => (double?)(x.Quantity * x.Price)) ?? 0; 
+1

Harika! Bu şekilde gitmek. – Mahmoodvcs

+1

Zekice Çalıştı! Teşekkürler @jitendra –

0

çözümler yukarıda benim için çalışmadı. Benim problemim benzerdi. Hiçbir satırın iade edilmediğinden emindim ama Sum garip bir şekilde davranıyordu. Bu yüzden lambda tarafından döndürülen satırların sayım özelliğini kontrol ettiğim lambda ifadesini çağırmadan hemen önce bir kontrol eklemeye karar verdim. Sıfırdan büyükse, o zaman toplam ifadesini ararım. Bu benim için çalıştı.

+0

Kodu gösterebilir misiniz? –

+0

TimeSheetRepository.GetAll(). (T => t.UserID == theUserId). Burada (t => t.Date> = startDate) .Where (t => t.Date <= endDate) .Sum (t => t.Hours); – Bryida

+0

Bu TimeSheetRepository.GetAll() gibi bir sayı olup olmadığını kontrol etmek zorundaydım. (T => t.UserID == theUserId). Burada (t => t.Date> = startDate) .Where (t => t.Date <= endDate) .Count()> 0 Onarılı olan saatlerin .Sum çağrılması her zaman yukarıdaki hataya neden olduğunda sonuçta hiçbir satır mevcut değildi – Bryida

0
join sim in ctx.EF.Collaterals on new { id = ini.cam.id, Type = 0 } equals new 
{ id = sim.CampaignId == null ? new Guid() : sim.CampaignId, sim.Type } 
into tempcoll 
from sim in tempcoll.DefaultIfEmpty() 

Sen değerini kontrol ve boş ise ikinci sütunda Guid yerleştirin ve ikinci table.and içinde işe yarayacak için üçlü operatörü kullanmak gerekir works.Actually Bu çözüm. "Materyal değeri" boş "olduğu için" Double "türünde değerlendirme başarısız oldu" çözüldü. Teşekkürler

İlgili konular