DbArithmeticExpression bağımsız değişkenlerinin sayısal bir ortak türü olmalıdır


120
TimeSpan time24 = new TimeSpan(24, 0, 0);
TimeSpan time18 = new TimeSpan(18, 0, 0);    

// first get today's sleeping hours
List<Model.Sleep> sleeps = context.Sleeps.Where(
    o => (clientDateTime - o.ClientDateTimeStamp < time24) && 
          o.ClientDateTimeStamp.TimeOfDay > time18 && 
          clientDateTime.TimeOfDay < time18 && 
          o.UserID == userid).ToList(); 

Bu Linq ifadesi bu istisnayı atar:

DbArithmeticExpression arguments must have a numeric common type.

Lütfen yardım et!


Sonuçları nedir clientDateTime - o.ClientDateTimeStamp?
shahkalpesh

Noramlly, bir TimeSpan nesnesi olmalıdır, EF istisnası atılır.
Nawaz Dhandala

Yanıtlar:


247

İle aritmetik DateTime, Entity Framework 6 ve öncesinde desteklenmez. DbFunctions * kullanmanız gerekir . Öyleyse, ifadenizin ilk kısmı için şöyle bir şey:

var sleeps = context.Sleeps(o =>
    DbFunctions.DiffHours(o.ClientDateTimeStamp, clientDateTime) < 24);

DiffHoursYöntemin kabul ettiğini unutmayın Nullable<DateTime>.

Varlık Çerçevesi çekirdeği (Sql Sunucusu ile kullanıldığında, belki diğer db sağlayıcıları) DateTime AddXxxişlevlerini destekler (gibi AddHours). DATEADDSQL'e çevrilirler .

* EntityFunctionsEntity Framework sürüm 6'dan önce.


2

Bunun eski bir soru olduğunu biliyorum, ancak sizin özel durumunuzda DBFunctions@GertArnold tarafından önerildiği gibi kullanmak yerine, işlemi Lambda'dan söz konusu aritmetik hareketini tersine çeviremez miydiniz?

Sonuçta clientDateTimeve time24sabit değerlerdir, bu nedenle farklarının her yinelemede yeniden hesaplanması gerekmez.

Sevmek:

TimeSpan time24 = new TimeSpan(24, 0, 0);
TimeSpan time18 = new TimeSpan(18, 0, 0);    

var clientdtminus24 = clientDateTime - time24;

// first get today's sleeping hours
List<Model.Sleep> sleeps = context.Sleeps.Where(
    o => (clientdtminus24 < o.ClientDateTimeStamp) && 
          o.ClientDateTimeStamp.TimeOfDay > time18 && 
          clientDateTime.TimeOfDay < time18 && 
          o.UserID == userid).ToList();

Bu yeniden düzenleme, genellikle bir sabit zaman damgası tarafından kaydırılan depolanan tarih saatini başka bir tarih saatiyle karşılaştırmaya çalışıyorsanız mümkündür.


Tam da bu durumdaydım ve bu yardımcı oldu. Bununla birlikte, bu çözümün kapsamı belirli bir tür problemle çok sınırlıdır.
Zimano

@Zimano Teknolojileri değiştirmesine veya hack'lere başvurmasına gerek kalmadan OP sorununu çözer. Eğer bu şekilde yeniden düzenlenebilirse, o zaman yapın, değilse, kabul edilen cevapta olduğu gibi yapın.
Yakında

1

Diğer taraftan, performans gerçek hedef değilse, kullanmayı deneyebilirsiniz AsEnumerable(). Yani, böyle olurdu

List<Model.Sleep> sleeps = context.Sleeps.AsEnumerable().Where(....

AsEnumerable () eklemek SQL sorgusunu varlığa dönüştürür ve bunlarda .Net işlevlerinin çalıştırılmasına izin verir. Daha fazla bilgi için AsEnumerable hakkında burayı kontrol edin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.