지정된 형식 멤버 'Date'는 LINQ to Entities Exception에서 지원되지 않습니다.


105

다음 문을 구현하는 동안 예외가 발생했습니다.

 DateTime result;
 if (!DateTime.TryParse(rule.data, out result))
     return jobdescriptions;
 if (result < new DateTime(1754, 1, 1)) // sql can't handle dates before 1-1-1753
     return jobdescriptions;
 return jobdescriptions.Where(j => j.JobDeadline.Date == Convert.ToDateTime(rule.data).Date );

예외

The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

예외의 의미는 알고 있지만 제거하는 방법을 모르겠습니다. 도움이 필요하세요?


이것은 EF6 이하입니다. EF 코어는 .Date.
Gert Arnold

답변:


102

LINQ to Entities는 동등한 SQL이 없기 때문에 대부분의 .NET Date 메서드 (사용한 캐스팅 포함)를 SQL로 변환 할 수 없습니다.

해결책은 LINQ 문 외부에서 Date 메서드를 사용한 다음 값을 전달하는 것입니다. Convert.ToDateTime (rule.data) .Date가 오류를 일으키는 것처럼 보입니다.

DateTime 속성에 대한 호출 날짜도 SQL로 변환 할 수 없으므로 해결 방법은 정수일 뿐이므로 LINQ로 변환 할 수있는 .Year .Month 및 .Day 속성을 비교하는 것입니다.

var ruleDate = Convert.ToDateTime(rule.data).Date;
return jobdescriptions.Where(j => j.Deadline.Year == ruleDate.Year 
                       && j.Deadline.Month == ruleDate.Month 
                       && j.Deadline.Day == ruleDate.Day);

6
j =>는 j.JobDeadline.Date어떻습니까?
성운

1
Date는 JobDeadline의 속성입니까? 이로 인해 자체적으로 오류가 발생해서는 안됩니다. 이름 충돌 일 수 있습니다 (하지만 확실하지 않음). 줄에서 여전히 오류가 발생하면 DeadlineDate 또는 이와 유사한 이름으로 변경하십시오.
유도

1
Date는 JobDeadline의 속성입니다. JobDeadline은 Date를 추출하려는 DateTime 유형입니다.
성운

그런 다음 LINQ 내에서이 작업을 수행하려면 JobDeadline 속성 (예 : j.JobDeadline> ruleDate)을 비교하면됩니다. 이것은 약간의 테스트가 필요하지만 작동하도록 만들 수 있습니다. 또는 .Month .Day 및 .Year의 세 가지 속성을 비교합니다 (j.Deadline.Year == ruleDate.Year && j j.Deadline.Month == ruleDate.Month && j.Deadline.Day == ruleDate.Day). 우아하지는 않지만 정수이기 때문에 작동합니다.
유도

흠. 이 아이디어는 효과가 있습니다. 더럽지 만 작동합니다. 답으로 쓰면 정답으로 표시 할 수 있습니다.
성운

230

EntityFunctionsTruncateTime 메서드를 사용 하여 속성을 SQL로 올바르게 변환 할 수 있습니다 .Date

using System.Data.Objects; // you need this namespace for EntityFunctions

// ...

DateTime ruleData = Convert.ToDateTime(rule.data).Date;
return jobdescriptions
    .Where(j => EntityFunctions.TruncateTime(j.JobDeadline) == ruleData);


업데이트 : EntityFunctions EF6에서 더 이상 사용되지 않음, 사용DbFunctions.TruncateTime


글쎄, 나는 그것이 유형이고 잘린 시간 ruleData이 있음을 알았습니다 . 기분이 좋지 않습니다. 예외가 발생하지 않았지만 예상 결과도 얻지 못했습니다. DateTimej.JobDeadline
성운

@aneal : 그것은 모든 레코드를 반환 JobDeadline같은이 날짜rule.data의 상관없이, 하루의 시간을 . 질문에서 쿼리로 달성하려는 것이 아닙니까? 왜 기분이 좋지 않습니까?
Slauma

1
+1 및 위 내용에 동의합니다. 구현의 99 %에 대해 확실히 더 나은 답변입니다
jim tollan 2013 년

26
참고 EntityFunctionsEF6에서 더 이상 사용되지 않습니다, 당신은 이제 사용해야합니다 DbFunctions.
Julien N

2
> EF6에서 DbFunctions에 대한 네임 스페이스입니다 System.Data.Entity: msdn.microsoft.com/en-us/library/Dn220142(v=VS.113).aspx
GraehamF


9

ef6의 "EntityFunctions.TruncateTime"또는 "DbFunctions.TruncateTime"이 작동하지만 빅 데이터에서 일부 성능 문제가 있습니다.

가장 좋은 방법은 다음과 같이 행동하는 것입니다.

DateTime ruleDate = Convert.ToDateTime(rule.data);

DateTime  startDate = SearchDate.Date;

DateTime  endDate = SearchDate.Date.AddDay(1);

return jobdescriptions.Where(j.Deadline >= startDate 
                       && j.Deadline < endDate );

날짜의 일부를 사용하는 것보다 낫습니다. 큰 데이터에서 쿼리가 더 빠르게 실행되기 때문입니다.


이 답변에 +1. EntityFunctions.TruncateTime(나중에로 대체 됨 DbFunctions.TruncateTime)은 날짜 시간이 문자열로 변환되고 잘리는 SQL로 변환하여 구현됩니다. 이렇게하면 처리 된 레코드 수에 비례하여 쿼리 실행 속도가 상당히 느려집니다.
urig

3

를 포함해야합니다 using System.Data.Entity;. 잘 작동합니다.ProjectTo<>

var ruleDate = rule.data.Date;
return jobdescriptions.Where(j => DbFunctions.TruncateTime(j.Deadline) == ruleDate);

로 이미 대답했다 여기
거트 아놀드

1

의미하는 바는 LINQ to SQL이 Date속성을 SQL 식으로 변환하는 방법을 모른다는 것 입니다. 이는 구조 의 Date속성이 DateTimeSQL에서 아날로그 가 없기 때문 입니다.


1

그것은 나를 위해 일했습니다.

DateTime dt = DateTime.Now.Date;
var ord = db.Orders.Where
      (p => p.UserID == User && p.ValidityExpiry <= dt);

출처 : Asp.net 포럼


0

나는 같은 문제가 있지만 DateTime-Ranges로 작업합니다. 내 솔루션은 시작 시간 (모든 날짜 포함)을 00:00:00으로, 종료 시간을 23:59:59로 조작하는 것이므로 더 이상 DateTime을 날짜로 변환하지 않고 DateTime으로 유지합니다.

DateTime이 하나만있는 경우 시작 시간 (모든 날짜 포함)을 00:00:00으로 설정하고 종료 시간을 23:59:59로 설정할 수도 있습니다. 그런 다음 마치 시간 범위 인 것처럼 검색합니다.

var from = this.setStartTime(yourDateTime);
var to = this.setEndTime(yourDateTime);

yourFilter = yourFilter.And(f => f.YourDateTime.Value >= from && f.YourDateTime.Value <= to);

DateTime-Range로도 할 수 있습니다.

var from = this.setStartTime(yourStartDateTime);
var to = this.setEndTime(yourEndDateTime);

yourFilter = yourFilter.And(f => f.YourDateTime.Value >= from && f.YourDateTime.Value <= to);

0

다음과 같이 Enum을 얻을 수 있습니다.

DateTime todayDate = DateTime.Now.Date; var check = db.tableName.AsEnumerable().Select(x => new
        {
            Date = x.TodayDate.Date
        }).Where(x => x.Date == todayDate).FirstOrDefault();

이것은 날짜 필터를 적용하기 위해 미리 테이블의 전체 내용을 효과적으로 열거하는 것입니다. 잠재적으로 매우 나쁜 생각 처럼 보입니다 !
Javier Rapoport 2019

0

여기에서 많은 사람들이 지적했듯이 TruncateTime 함수를 사용하는 것은 느립니다.

가능한 경우 가장 쉬운 옵션은 EF Core를 사용하는 것입니다. 할 수 있습니다. 할 수없는 경우 자르기에 대한 더 나은 대안은 쿼리 된 필드를 전혀 변경하지 않고 경계를 수정하는 것입니다. 하한과 상한이 선택 사항 인 일반적인 '사이'유형 쿼리를 수행하는 경우 다음이 트릭을 수행합니다.

    public Expression<Func<PurchaseOrder, bool>> GetDateFilter(DateTime? StartDate, DateTime? EndDate)
    {
        var dtMinDate = (StartDate ?? SqlDateTime.MinValue.Value).Date;
        var dtMaxDate = (EndDate == null || EndDate.Value == SqlDateTime.MaxValue.Value) ? SqlDateTime.MaxValue.Value : EndDate.Value.Date.AddDays(1);
        return x => x.PoDate != null && x.PoDate.Value >= dtMinDate && x.PoDate.Value < dtMaxDate;
    }

기본적으로 PoDate를 Date 부분으로 다시 트리밍하는 대신 <= 대신 상위 쿼리 경계와 사용자 <를 증가시킵니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.