DateTime and LinqToEntities - linq

I have DateTime field, which storing date + time. I need to use only date part, so I try:
query = query.Where(p => p.CreatedDateTime.Date == DateStart);
but I get the following error:
The specified type member 'Date' is not supported in LINQ to Entities.
Only initializers, entity members, and entity navigation properties
are supported.
why and how to fix it?

what about this:
query = query.Where(p => EntityFunctions.TruncateTime(p.CreatedDateTime) == DateStart);

You cannot use extension functions in LINQ queries that result in a database hit if Entity Framework has no way to convert this into valid SQL.
There may be a more compact solution but the following should work fine:
query = query.Where(p =>
p.CreatedDateTime.Year == DateStart.Year &&
p.CreatedDateTime.Month == DateStart.Month &&
p.CreatedDateTime.Day == DateStart.Day);

Related

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

Using this code in Entity Framework I receive the following error. I need to get all the rows for a specific date, DateTimeStart is of type DataType in this format 2013-01-30 12:00:00.000
Code:
var eventsCustom = eventCustomRepository.FindAllEventsCustomByUniqueStudentReference(userDevice.UniqueStudentReference)
.Where(x => x.DateTimeStart.Date == currentDateTime.Date);
Error:
base {System.SystemException} = {"The specified type member 'Date' is
not supported in LINQ to Entities. Only initializers, entity members,
and entity navigation properties are supported."}
Any ideas how to fix it?
DateTime.Date cannot be converted to SQL. Use EntityFunctions.TruncateTime method to get date part.
var eventsCustom = eventCustomRepository
.FindAllEventsCustomByUniqueStudentReference(userDevice.UniqueStudentReference)
.Where(x => EntityFunctions.TruncateTime(x.DateTimeStart) == currentDate.Date);
UPDATE: As #shankbond mentioned in comments, in Entity Framework 6 EntityFunctions is obsolete, and you should use DbFunctions class, which is shipped with Entity Framework.
You should now use DbFunctions.TruncateTime
var anyCalls = _db.CallLogs.Where(r => DbFunctions.TruncateTime(r.DateTime) == callDateTime.Date).ToList();
EntityFunctions is obsolete. Consider using DbFunctions instead.
var eventsCustom = eventCustomRepository.FindAllEventsCustomByUniqueStudentReference(userDevice.UniqueStudentReference)
.Where(x => DbFunctions.TruncateTime(x.DateTimeStart) == currentDate.Date);
I would like to add a solution, that have helpt me to solve this problem in entity framework:
var eventsCustom = eventCustomRepository.FindAllEventsCustomByUniqueStudentReference(userDevice.UniqueStudentReference)
.Where(x => x.DateTimeStart.Year == currentDateTime.Year &&
x.DateTimeStart.Month== currentDateTime.Month &&
x.DateTimeStart.Day == currentDateTime.Day
);
I hope that it helps.
Always use EntityFunctions.TruncateTime() for both x.DateTimeStart and currentDate.
such as :
var eventsCustom = eventCustomRepository.FindAllEventsCustomByUniqueStudentReference(userDevice.UniqueStudentReference).Where(x => EntityFunctions.TruncateTime(x.DateTimeStart) == EntityFunctions.TruncateTime(currentDate));
Just use simple properties.
var tomorrow = currentDateTime.Date + 1;
var eventsCustom = eventCustomRepository.FindAllEventsCustomByUniqueStudentReference(userDevice.UniqueStudentReference)
.Where(x => x.DateTimeStart >= currentDateTime.Date
and x.DateTimeStart < tomorrow);
If future dates are not possible in your app, then >= x.DateTimeStart >= currentDateTime.Date is sufficient.
if you have more complex date comparisons, then check Canonical functions
and if you have EF6+ DB functions
More Generally - For people searching for issues Supported Linq methods in EF
can explain similar issues with linq statements that work on Memory base Lists but not in EF.
Simplified:
DateTime time = System.DateTime.Now;
ModelName m = context.TableName.Where(x=> DbFunctions.TruncateTime(x.Date) == time.Date)).FirstOrDefault();
Use the bellow code for using EF6:
(DbFunctions.TruncateTime(x.User.LeaveDate.Value)
I have the same issue with Entity Framework 6.1.3
But with different scenario. My model property is of type nullable DateTime
DateTime? CreatedDate { get; set; }
So I need to query on today's date to check all the record, so this what works for me. Which means I need to truncate both records to get the proper query on DbContext:
Where(w => DbFunctions.TruncateTime(w.CreatedDate) == DbFunctions.TruncateTime(DateTime.Now);
Another solution could be:
var eventsCustom = eventCustomRepository.FindAllEventsCustomByUniqueStudentReference(userDevice.UniqueStudentReference).AsEnumerable()
.Where(x => x.DateTimeStart.Date == currentDate.Date).AsQueryable();
I've faced this same issue and it seems that it is really caused by the presence of a call to the .Date property within the Where method. When removed, the error disappears. Consider that calling the .Date property on any side of the comparison operator causes this error. Calling the .Date property outside and before the Where method is enough to solve this error.

date comparison in EF query

I have a EF query in which i'm using lambda expressions, when i try to get the difference between two dates, it throws me exception
The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
my query is
var unApprovedLeaves = db.Leaves.Where(l => l.Status.Id == 1 && ((System.DateTime.Now.Date - l.ToDate.Date).TotalDays)==0)
.Include("Employee")
.Include("Employee.Manager")
.ToList();
can anyone tell me how do i get this thing right?
You must use SqlFunctions helper from System.Data.Objects.SqlClient. Try this:
var today = DateTime.Now.Date;
var unApprovedLeaves = db.Leaves.Where(l => l.Status.Id == 1 &&
(SqlFunctions.DateDiff("day", today, l.ToDate))==0)
.Include("Employee")
.Include("Employee.Manager")
.ToList();
In Entity Framework it is recomended to use DbFunctions helper from System.Data.Entity
Try this:
var today = DateTime.Now.Date;
var unApprovedLeaves = db.Leaves.Where(l => l.Status.Id == 1 &&
(DbFUnction.DiffDays(today, l.ToDate))==0)
.Include("Employee")
.Include("Employee.Manager")
.ToList();

Entity Framework: Best way to query for a set of dates using Linq

I have a set of unique DateTimes (without time portion) that the user can select from the user interface. This is not only a range like "LastWeek" or "LastMonth". The user can selcet every single day he wants.
What might be the best way to Linq-query in EntityFramework for matching results? I have a table Foo with an Attribute CreatedAt, which stores information with time portion. Of course I dont want to check the CreatedAt-Property on client side, SqlServer should do the job for me.
I think it should be someting like:
var query = _entities.Foo.Where(x => x.UserID == user.ID);
if (selectedDates.IsNullOrEmpty() == false)
query = query.Where(x => x.CreatedAt 'IsIn' selectedDates);
or:
foreach (var date in selectedDates)
query = query.Where(x => x.CreatedAt.Year == date.Year && x.Month == date.Month && x.Day == date.Month) //but of course here I have the problem that I have to use the 'Or'-Operator, not 'And'.
How can I accomplish this?
You can use EntityFunctions.TruncateTime() to perform a truncation of the date on the server. Then something along the lines of this should work.
query = query.Where(x => selectedDates.Contains(EntityFunctions.TruncateTime(x));
You can call the Contains extension method on selectedDates. Entity Framework 4.0 will understand this and will translate it to an IN operator in SQL:
if (selectedDates.IsNullOrEmpty() == false)
query = query.Where(x => selectedDates.Contains(x.CreatedAt));
Try query = query.Where(x => selectedDates.Contains(x.CreatedAt));

How to convert a LINQ query from query syntax to query method

Linq and EF4.
I have this Linq query in query syntax I would like convert into query method.
Are you able to do it? I tried more tha 2 hours without success :-(
Thanks for your time
CmsContent myContentObj = (from cnt in context.CmsContents
from categoy in cnt.CmsCategories
where categoy.CategoryId == myCurrentCategoryId && cnt.ContentId == myCurrentContentId
select cnt).Single();
My original answer selected the wrong item. It's a bit more complicated than what I had (which Ani has posted). Here's what I believe is an equivalent query however and should perform better:
CmsContent myContentObj =
context.CmsContents
.Where(cnt => cnt.ContentId == myCurrentId
&& cnt.CmsCategories
.Any(categoy => categoy.CategoryId == myCurrentCategoryId))
.Single();
Here is a non-direct translation that I believe performs the same task in much less code:
var myContentObj = context.CmsContents.Single(
x => x.ContentId == myCurrentContentId &&
x.CmsCategories.Any(y => y.CategoryId == myCurrentCategoryId)
);
Here's how the C# compiler actually does it, with some help from .NET Reflector to verify:
var myContentObj = context
.CmsContents
.SelectMany(cnt => cnt.CmsCategories,
(cnt, categoy) => new { cnt, categoy })
.Where(a => a.categoy.CategoryId == myCurrentCategoryId
&& a.cnt.ContentId == myCurrentContentId)
.Select(a => a.cnt)
.Single();
Essentially, the 'nested' from clauses results in a SelectMany call with a transparent identifier (an anonymous-type instance holding the 'parent' cnt and the 'child' categoy). The Where filter is applied on the anonymous-type instance, and then we do another Select projection to get back the 'parent'. The Single call was always 'outside' the query expression of course, so it should be obvious how that fits in.
For more information, I suggest reading Jon Skeet's article How query expressions work.

compare the dates with linq

I have this code:
i.SpesaVitto = db.TDP_NotaSpeseSezB.Where(p => p.GiornoFine == null &&
((DateTime)p.Giorno).Date == ((DateTime)i.Data).Date &&
p.MissioneID == missioneID).Sum(p => p.Costo);
If i launch it i obtain this error:
The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
how can i compare the datetimes field without the hours part
thanks
Well this is certainly not the most efficient way to do it, but you can try something like:
i.SpesaVitto = db.TDP_NotaSpeseSezB.Where(p => p.GiornoFine == null &&
(new DateTime((p.Giorno as DateTime).Year, (p.Giorno as DateTime).Month, (p.Giorno as DateTime).Day) == (new DateTime((i.Data as DateTime).Year, (i.Data as DateTime).Month, (i.Data as DateTime).Day) &&
p.MissioneID == missioneID).Sum(p => p.Costo);
Depending on the requirements I would probably implement something cleaner and faster but it would depend on how the dates are stored in your database.
Check out this question it looks like the syntax error may be in your SQL, not in your LINQ. The asker in that question had written:
SQL ------
Select
EmployeeNameColumn
From
EmployeeTable
WHERE StartDateColumn.Date <= GETDATE() //Today
SQL ------
When they should have written:
SQL ------
Select
EmployeeNameColumn
From
EmployeeTable
WHERE StartDateColumn <= GETDATE() //Today
SQL -
solution for your problem will be the "SqlFunctions class and DateDiff" http://msdn.microsoft.com/en-us/library/system.data.objects.sqlclient.sqlfunctions.aspx

Resources