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.
도와주세요!
답변
DateTime
Entity Framework 6 이하에서는 산술 연산 이 지원되지 않습니다. DbFunctions * 를 사용해야 합니다. 따라서 진술의 첫 번째 부분은 다음과 같습니다.
var sleeps = context.Sleeps(o =>
DbFunctions.DiffHours(o.ClientDateTimeStamp, clientDateTime) < 24);
이 DiffHours
메서드는 Nullable<DateTime>
.
Entity Framwork 코어 (Sql Server, 아마도 다른 DB 공급자와 함께 사용되는 경우)는 DateTime AddXxx
함수 (예 :)를 지원합니다 AddHours
. 그들은 DATEADD
SQL 로 번역됩니다 .
* EntityFunctions
Entity Framework 버전 6 이전
답변
나는 이것이 오래된 질문이라는 것을 알고 있지만 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();
이 리팩터링은 일반적으로 수정 타임 스탬프에 의해 이동 된 저장된 날짜 시간을 다른 날짜 시간과 비교하려는 경우 가능합니다.
답변
다른 방법으로 성능이 진정한 목표가 아닌 경우 AsEnumerable()
. 그래서 그것은
List<Model.Sleep> sleeps = context.Sleeps.AsEnumerable().Where(....
AsEnumerable ()을 추가하면 SQL 쿼리가 엔티티로 변환되고 여기에서 .Net 함수를 실행할 수 있습니다. 자세한 내용 은 AsEnumerable에 대해 여기 를 확인하십시오.