Element członkowski określonego typu „Data” nie jest obsługiwany w LINQ to Entities. Tylko inicjatory, elementy członkowskie jednostek i właściwości nawigacji jednostek

138

Używając tego kodu w Entity Framework otrzymuję następujący błąd. Muszę uzyskać wszystkie wiersze dla określonej daty, DateTimeStartjest typu DataType w tym formacie2013-01-30 12:00:00.000

Kod:

 var eventsCustom = eventCustomRepository.FindAllEventsCustomByUniqueStudentReference(userDevice.UniqueStudentReference)
                    .Where(x =>  x.DateTimeStart.Date == currentDateTime.Date);

Błąd:

base {System.SystemException} = {"Element członkowski określonego typu 'Date' nie jest obsługiwany w LINQ to Entities. Obsługiwane są tylko inicjatory, elementy członkowskie jednostki i właściwości nawigacji po jednostkach."}

Jakieś pomysły, jak to naprawić?

GibboK
źródło
Mogę używać x.DateTimeStart.Date w EF Core 2.1.1
Kirsten Greed

Odpowiedzi:

271

DateTime.Datenie można przekonwertować na SQL. Użyj metody EntityFunctions.TruncateTime , aby pobrać część daty.

var eventsCustom = eventCustomRepository
.FindAllEventsCustomByUniqueStudentReference(userDevice.UniqueStudentReference)
.Where(x => EntityFunctions.TruncateTime(x.DateTimeStart) == currentDate.Date);

AKTUALIZACJA: Jak wspomniano w komentarzach @shankbond, w Entity Framework 6 EntityFunctionsjest przestarzały i należy używać DbFunctionsklasy, która jest dostarczana z Entity Framework.

Sergey Berezovskiy
źródło
1
Muszę nieznacznie zmodyfikować twoją wersję. Gdzie (x => EntityFunctions.TruncateTime (x.DateTimeStart) == currentDate.Date); daj mi znać, co myślisz
GibboK
1
Mam nadzieję, że nie masz nic przeciwko edycji, dodając .date, jeśli się zgadzasz, więc tylko w celach informacyjnych :-) Dziękuję za wsparcie, naprawdę to doceniam
GibboK
1
@GibboK oczywiście, nie ma problemu :) To było tylko w celu sformatowania długiego ciągu.
Sergey Berezovskiy
68
EntityFunctions jest przestarzałe, zamiast tego użyj metody
DbFunctions.TruncateTime
1
Element członkowski określonego typu „Data” nie jest obsługiwany w LINQ to Entities. Obsługiwane są tylko inicjatory, elementy członkowskie jednostek i właściwości nawigacji jednostek.
SAR
83

Powinieneś teraz użyć DbFunctions.TruncateTime

var anyCalls = _db.CallLogs.Where(r => DbFunctions.TruncateTime(r.DateTime) == callDateTime.Date).ToList();
WaZ
źródło
Element członkowski określonego typu „Data” nie jest obsługiwany w LINQ to Entities. Obsługiwane są tylko inicjatory, elementy członkowskie jednostek i właściwości nawigacji jednostek.
SAR
17

Chciałbym dodać rozwiązanie, które pomogło mi rozwiązać ten problem we frameworku podmiotowym:

var eventsCustom = eventCustomRepository.FindAllEventsCustomByUniqueStudentReference(userDevice.UniqueStudentReference)
                .Where(x =>  x.DateTimeStart.Year == currentDateTime.Year &&
                             x.DateTimeStart.Month== currentDateTime.Month &&
                             x.DateTimeStart.Day == currentDateTime.Day
    );

Mam nadzieję, że to pomoże.

jvrdelafuente
źródło
15

EntityFunctionsjest przestarzały. Rozważ użycie DbFunctionszamiast tego.

var eventsCustom = eventCustomRepository.FindAllEventsCustomByUniqueStudentReference(userDevice.UniqueStudentReference)
   .Where(x => DbFunctions.TruncateTime(x.DateTimeStart) == currentDate.Date);
Leonel Sanches da Silva
źródło
8

Zawsze używaj EntityFunctions.TruncateTime () zarówno dla x.DateTimeStart, jak i currentDate. Jak na przykład :

var eventsCustom = eventCustomRepository.FindAllEventsCustomByUniqueStudentReference(userDevice.UniqueStudentReference).Where(x => EntityFunctions.TruncateTime(x.DateTimeStart) == EntityFunctions.TruncateTime(currentDate));
Babul Mirdha
źródło
5

Po prostu użyj prostych właściwości.

var tomorrow = currentDateTime.Date + 1;  
var eventsCustom = eventCustomRepository.FindAllEventsCustomByUniqueStudentReference(userDevice.UniqueStudentReference)
                            .Where(x =>  x.DateTimeStart >= currentDateTime.Date 
                                   and x.DateTimeStart < tomorrow);

Jeśli przyszłe daty nie są możliwe w Twojej aplikacji, wystarczy > = x.DateTimeStart> = currentDateTime.Date .

jeśli masz bardziej złożone porównania dat, sprawdź Funkcje kanoniczne i jeśli masz funkcje EF6 + DB

Bardziej ogólnie - dla osób szukających problemów Obsługiwane metody Linq w EF mogą wyjaśnić podobne problemy z instrukcjami linq, które działają na listach bazowych pamięci, ale nie w EF.

phil soady
źródło
3

Uproszczony:

DateTime time = System.DateTime.Now;
ModelName m = context.TableName.Where(x=> DbFunctions.TruncateTime(x.Date) == time.Date)).FirstOrDefault();
devlin carnate
źródło
2

Użyj poniższego kodu do korzystania z EF6:

(DbFunctions.TruncateTime(x.User.LeaveDate.Value)
Abdus Salam Azad
źródło
0

Innym rozwiązaniem mogłoby być:

var eventsCustom = eventCustomRepository.FindAllEventsCustomByUniqueStudentReference(userDevice.UniqueStudentReference).AsEnumerable()
   .Where(x => x.DateTimeStart.Date == currentDate.Date).AsQueryable();
cozmin-calin
źródło