อาร์กิวเมนต์ DbArithmeticExpression ต้องมีประเภทตัวเลขร่วมกัน


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(); 

นิพจน์ Linq นี้แสดงข้อยกเว้นนี้:

DbArithmeticExpression arguments must have a numeric common type.

กรุณาช่วย!


ผลลัพธ์clientDateTime - o.ClientDateTimeStampคืออะไร?
shahkalpesh

noramlly ที่ควรเป็นวัตถุของ TimeSpan ใน EF ข้อยกเว้นจะถูกโยนทิ้ง
Nawaz Dhandala

คำตอบ:


247

DateTimeไม่สนับสนุนการคำนวณด้วยใน Entity Framework 6 และรุ่นก่อนหน้า คุณต้องใช้DbFunctions * ดังนั้นสำหรับส่วนแรกของคำแถลงของคุณสิ่งที่ต้องการ:

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

โปรดทราบว่าวิธีการที่ยอมรับDiffHoursNullable<DateTime>

Entity Framwork core (เมื่อใช้กับ Sql Server อาจเป็นผู้ให้บริการ db รายอื่น) รองรับAddXxxฟังก์ชันDateTime (เช่นAddHours) แปลเป็นภาษาDATEADDSQL

* EntityFunctionsก่อน Entity Framework เวอร์ชัน 6


2

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ในกรณีเฉพาะของคุณแทนที่จะใช้ DBFunctionsตามที่แนะนำโดย @GertArnold คุณไม่สามารถเปลี่ยนการดำเนินการย้ายเลขคณิตที่เป็นปัญหาออกจาก Lambda ได้หรือไม่?

หลังจากที่ทุกคนclientDateTimeและtime24มีค่าการแก้ไขเพื่อให้ความแตกต่างของพวกเขาไม่จำเป็นต้องได้รับการคำนวณใหม่ทุกซ้ำ

ชอบ:

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();

โดยปกติตัวรีแฟคเตอร์นี้จะเป็นไปได้หากคุณพยายามเปรียบเทียบวันที่และเวลาที่จัดเก็บที่เลื่อนโดยการประทับเวลาแก้ไขกับวันที่และเวลาอื่น


ฉันมีสถานการณ์ที่แน่นอนนี้และสิ่งนี้ช่วยได้ อย่างไรก็ตามขอบเขตของการแก้ปัญหานี้ จำกัด เฉพาะปัญหาบางประเภทเท่านั้น
Zimano

@ Zimano ช่วยแก้ปัญหา OPs โดยไม่ต้องให้เขาเปลี่ยนเทคโนโลยีหรือหันไปใช้แฮ็ก หากสามารถ refactored เช่นนี้ให้ทำถ้าไม่ทำเช่นนั้นในคำตอบที่ยอมรับ
SoonDead

1

วิธีอื่น ๆ AsEnumerable()ถ้าผลการดำเนินงานไม่ได้เป็นเป้าหมายจริงคุณสามารถลองใช้ ดังนั้นมันจะเป็นอย่างไร

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

การเพิ่ม AsEnumerable () จะแปลงแบบสอบถาม SQL เป็นเอนทิตีและอนุญาตให้เรียกใช้ฟังก์ชัน. Net สำหรับข้อมูลเพิ่มเติมโปรดดูที่นี่เกี่ยวกับ AsEnumerable

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.