I have a DateTime column in a SQL Server database. The data stored as follows:
2020-10-04 23:45:00.527
I tried to compare the date as follows with current date (Date in database should be less than current date)
DateTime today = DateTime.Now.Date;
var result = (from c in TableName
where (c.Email == email) &&
c.Password == password && c.Status == 1 &&
c.ValidTill.Date <= today
select c).ToList();
But unfortunately I get this exception
'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported
Even tried the below method, that doesn't seem to work:
DbFunctions.TruncateTime(c.ValidTill)
My comparison would be like this -
2020-10-04 23:45:00 (Datetime in database) <= 2020-10-10 23:00:00 (current date & time)
You don't need .Date
c.ValidTill <= today
or comparing only with date
EntityFunctions.TruncateTime(x.ValidTill) <= today.Date
needs to do the work.
var today = DateTime.Now;
var result = (from c in TableName
where (c.Email == email) &&
c.Password == password && c.Status == 1 &&
c.ValidTill <= today
select c).ToList();
hope it will work.
Related
I'm a beginner in Linq queries and I'm wondering if my query can be improved one way ore another:
long vehid = json.VehicleId.Value;
DateTime date = DateTime.Parse(json.date.Value);
var Alerts = (from t2 in entities.Alerts.AsNoTracking()
where
t2.GeneratedTimeLocal.Year == date.Year
&& t2.GeneratedTimeLocal.Month == date.Month
&& t2.GeneratedTimeLocal.Day == date.Day
&& (t2.AlertType == 2 || t2.AlertType == 3)
&& t2.vId == vid
select new
{
GeneratedTimeLocal = t2.GeneratedTimeLocal,
OptionalText = t2.OptionalText
});
return Alerts;
The problem is that the Alerts datatable has a huge amount of data in it that increases day by day and right now it's kind of slow.
The GeneratedTimeLocal field from Alerts datatable is type datetimeoffset(7).
Is there a way to improve this query?
Define a date range to improve the query. Then check the query execution plan and based on that decide if you need a new index or change existing indexes.
long vehid = json.VehicleId.Value;
DateTime dateFrom = DateTime.Parse(json.date.Value).Date; // date with no time
DateTime dateTo = dateFrom.AddDays(1); // add one day to create the date range
var Alerts = (from t2 in entities.Alerts.AsNoTracking()
where
t2.GeneratedTimeLocal >= dateFrom
&& t2.GeneratedTimeLocal <= dateTo
&& (t2.AlertType == 2 || t2.AlertType == 3)
&& t2.vId == vid
select new
{
GeneratedTimeLocal = t2.GeneratedTimeLocal,
OptionalText = t2.OptionalText
});
return Alerts;
On the other hand, remember that this query won't be executed until you do a ToList(), for example.
Try this index:
CREATE INDEX IX_Alert_GeneratedTimeLocal_vId_AlertType_with_include ON Alert(GeneratedTimeLocal, vId, AlertType) INCLUDE(OptionalText)
I'm assuming you're using SQL Server. You could also try a filtered index if the table is huge. Check out this link: https://learn.microsoft.com/en-us/sql/relational-databases/indexes/create-filtered-indexes
I am trying to execute the following code and am receiving an error
public List<Log> GetLoggingData(DateTime LogDate, string title)
{
var context = new LoggingEntities();
var query = from t in context.Logs
where t.Title == title
&& t.Timestamp == LogDate
select t;
return query.ToList();
}
The error I'm receiving is "The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported." I have tried various attempts of casting everythign to a string, only comparing the date part, but can't seem to get the right combinaation. Any help is greatly appreciated.
If you are using EF 6.0+, you can use DbFunctions.TruncateTime(DateTime?) :
var query =
from t in context.Logs
where t.Title == title
&& DbFunctions.TruncateTime(t.Timestamp) == LogDate.Date
select t;
Note: For earlier version of EF where DbFunctions isn't available, EntityFunctions.TruncateTime(DateTime?) can be used instead.
Not the greatest solution, but it works. For a variety of reasons, I have to use .net 3.5 at this point and modifying the database would be difficult. Anyways, here is a solution that works:
var query = from t in context.Logs
where t.Title == title
&& t.Timestamp.Day == LogDate.Day
&& t.Timestamp.Month == LogDate.Month
&& t.Timestamp.Year == LogDate.Year
select t;
Not the most elegant solution, but it is effective.
EntityFunctions.TruncateTime(t.Timestamp) is obsolete from EF6.
Use below
DbFunctions.TruncateTime(t.Timestamp)
Always use EntityFunctions.TruncateTime() for both x.DateTimeStart and LogDate.
such as :
var query = from t in context.Logs
where t.Title == title
&& EntityFunctions.TruncateTime(t.Timestamp) == EntityFunctions.TruncateTime(LogDate)
select t;
Correct me if I'm wrong, but in mikemurf22's example, it would need to check each part of the date component, and potentially a lot more server processing?
Anyway, I stumbled across this problem, and this is my solution.
Assuming that you're going to be passing in the date component only, you can find the last minute of the day that you pass in, and use the where clause to define the range.
public List<Log> GetLoggingData(DateTime LogDate, string title)
{
DateTime enddate = new DateTime(LogDate.Year, LogDate.Month, LogDate.Day, 23, 59, 59)
var query = from t in context.Logs
where t.Timestamp >= date
where t.Timestamp <= enddate
select t;
return query.ToList();
}
Convert LongDate to .ToShortDateStringand then you can use it this way:
EntityFunctions.TruncateTime(t.Timestamp) == LogDate
like mike did
Try this:
var calDate = DateTime.Now.Date.AddDays(-90);
var result = return (from r in xyz where DbFunctions.TruncateTime(r.savedDate) >= DbFunctions.TruncateTime(calDate)
You can use this hack:
DateTime startDate = LogDate.Date;
DateTime endDate = LogDate.Date.AddDays(1);
var query = from t in context.Logs
where t.Title == title
&& t.Timestamp >= startDate
&& t.Timestamp < endDate
select t;
I am trying to execute the following code and am receiving an error
public List<Log> GetLoggingData(DateTime LogDate, string title)
{
var context = new LoggingEntities();
var query = from t in context.Logs
where t.Title == title
&& t.Timestamp == LogDate
select t;
return query.ToList();
}
The error I'm receiving is "The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported." I have tried various attempts of casting everythign to a string, only comparing the date part, but can't seem to get the right combinaation. Any help is greatly appreciated.
If you are using EF 6.0+, you can use DbFunctions.TruncateTime(DateTime?) :
var query =
from t in context.Logs
where t.Title == title
&& DbFunctions.TruncateTime(t.Timestamp) == LogDate.Date
select t;
Note: For earlier version of EF where DbFunctions isn't available, EntityFunctions.TruncateTime(DateTime?) can be used instead.
Not the greatest solution, but it works. For a variety of reasons, I have to use .net 3.5 at this point and modifying the database would be difficult. Anyways, here is a solution that works:
var query = from t in context.Logs
where t.Title == title
&& t.Timestamp.Day == LogDate.Day
&& t.Timestamp.Month == LogDate.Month
&& t.Timestamp.Year == LogDate.Year
select t;
Not the most elegant solution, but it is effective.
EntityFunctions.TruncateTime(t.Timestamp) is obsolete from EF6.
Use below
DbFunctions.TruncateTime(t.Timestamp)
Always use EntityFunctions.TruncateTime() for both x.DateTimeStart and LogDate.
such as :
var query = from t in context.Logs
where t.Title == title
&& EntityFunctions.TruncateTime(t.Timestamp) == EntityFunctions.TruncateTime(LogDate)
select t;
Correct me if I'm wrong, but in mikemurf22's example, it would need to check each part of the date component, and potentially a lot more server processing?
Anyway, I stumbled across this problem, and this is my solution.
Assuming that you're going to be passing in the date component only, you can find the last minute of the day that you pass in, and use the where clause to define the range.
public List<Log> GetLoggingData(DateTime LogDate, string title)
{
DateTime enddate = new DateTime(LogDate.Year, LogDate.Month, LogDate.Day, 23, 59, 59)
var query = from t in context.Logs
where t.Timestamp >= date
where t.Timestamp <= enddate
select t;
return query.ToList();
}
Convert LongDate to .ToShortDateStringand then you can use it this way:
EntityFunctions.TruncateTime(t.Timestamp) == LogDate
like mike did
Try this:
var calDate = DateTime.Now.Date.AddDays(-90);
var result = return (from r in xyz where DbFunctions.TruncateTime(r.savedDate) >= DbFunctions.TruncateTime(calDate)
You can use this hack:
DateTime startDate = LogDate.Date;
DateTime endDate = LogDate.Date.AddDays(1);
var query = from t in context.Logs
where t.Title == title
&& t.Timestamp >= startDate
&& t.Timestamp < endDate
select t;
I´ve come to a total stop with my program and im in need of some help.
I got an xml file with customer billings and billing dates. This file has about 4000 billing dates. What i want is to sort them so the once that is in a range of a period date of 2010-04-01 - 2011-03-31 adds to a table column named period1. And the other dates goes to period2 that is 2011-04-01 - 2012-03-31.
Ive been testing and testing this solution in diffrent ways but it wont work. Im adding all the dats to a list named dates. And trying:
if (dates.All(date => date >= startDatePeriod1 && date <= stopDatePeriod1))
{
adapterBonus.InsertPeriod1Query(// insert to database));
}
else if (dates.All(date => date >= startDatePeriod2 && date >= stopDatePeriod2))
{
adapterBonus.InsertPeriod2Query(// insert to database));
}
startDatePeriod1 = 2010-04-01
stopDatePeriiod1 = 2011-03-31
and so on
The Enumerable.All extension method returns true if every element in the sequence verifies the condition. If dates contains dates in both periods, none of the ifs will run, because both calls to Enumerable.All will return false.
I'm not sure what you mean by "adds to a table column named period1", but if you mean to count all the dates in each period, use Enumerable.Count:
int period1Count = dates.Count(date => date >= startDatePeriod1 && date <= stopDatePeriod1);
int period2Count = dates.Count(date => date >= startDatePeriod2 && date <= stopDatePeriod2);
adapterBonus.InsertPeriod1Query(period1Count);
adapterBonus.InsertPeriod2Query(period2Count);
What you are doing, is the following:
Check whether ALL dates are in period one. If so, insert them into period 1 in the database. If not, check whether ALL dates are in period two and insert them into period 2 in the database.
You want to do the following:
foreach (var period1Date in dates.Where(date => date >= startDatePeriod1 &&
date <= stopDatePeriod1))
{
adapterBonus.InsertPeriod1Query(// insert period1Date to database));
}
foreach (var period2Date in dates.Where(date => date >= startDatePeriod2 &&
date <= stopDatePeriod2))
{
adapterBonus.InsertPeriod2Query(// insert period2Date to database));
}
BTW: I fixed an error in your second condition. It should be date <= stopDatePeriod2 instead of date >= stopDatePeriod2!
All return a boolean specifying whether all elements satisfy a condition. What you need is a Where() to extract those you need.
Something like:
adapterBonus.InsertPeriod1Query(dates.Where(date => date >= startDatePeriod1 && date <= stopDatePeriod1));
adapterBonus.InsertPeriod2Query(dates.Where(date => date >= startDatePeriod2 && date <= stopDatePeriod2));
Try this:
var period1Dates = dates.Where(date => date >= startDatePeriod1 && date <= stopDatePeriod1);
var period2Dates = dates.Where(date => date >= startDatePeriod2 && date >= stopDatePeriod2);
foreach(var date in period1Dates)
{ adapterBonus.InsertPeriod1Query(// insert to database)); }
etc.
easiest way to do this is doing a
startDatePeriod1 = 2010-04-01;
stopDatePeriod1 = 2011-03-01;
startDatePeriod2 = 2011-04-01;
stopDatePeriod2 = 2012-03-01;
foreach(DateTime d in dates) {
if (d => startDatePeriod1 && d <= startDatePeriod1) {
adapterBonus.InsertPeriod1Query(// insert to database));
} else if(d => startDatePeriod2 && d <= stopDatePeriod2) {
adapterBonus.InsertPeriod2Query(// insert to database));
}
}
seems like you just need a simple query for each bonus period, something like ...
var period1Dates = date.Where(date => date >= startDate1 && date <= stopDate1);
var period2Dates = date.Where(date => date >= startDate2 && date <= stopDate2);
adapterBonus.InsertPeriod1(period1Dates);
adapterBonus.InsertPeriod2(period2Dates);
As Daniel says, you're checking if all the dates are within each period, which it sound like will never be true, so nothing will be happening.
I'm using linq-to-sql for a query like this:
public static List<MyModel> GetData(int TheUserID, DateTime TheDate)
using (MyDataContext TheDC = new MyDataContext())
{
var TheOutput = from a in TheDC.MyTable
where a.UserID == TheUserID
(where a.Date1.Month == TheDate.Month && where a.Date1.Year == TheDate.Year)
OR
(where a.Date2.Month == TheDate.Month && where a.Date2.Year == TheDate.Year)
group a by a.Date1.Date AND by a.Date2.Date into daygroups
select new MyModel{...};
How do I write this to make the OR and the AND statement work? I've tried putting a || and a && in place but it doesn't work and I'm stuck on this query.
Basically, it should return a list of days within a month and in the MyModel, I do counts. For instance, in a column I count the number of appointments set on a given day and in another column I count the number of appointments attended on the same day. Date1 refers to the date the appointments are set and Date2 refers to the dates the appointments are attended. So for example, on March 3rd 2011, I've set 4 appointments (Date1 is 3/11/2011 for these) and they're set for various dates in the future (Date2). During the same date (March 3rd is Date2 this time), I've also attended several other appointments that were set on other dates in the past.
Thanks for any suggestions.
using (MyDataContext TheDC = new MylDataContext())
{
var TheOutput = from a in TheDC.MyTable
where a.UserID == TheUserID &&
(a.Date1.Month == TheDate.Month && a.Date1.Year == TheDate.Year)
||
( a.Date2.Month == TheDate.Month && a.Date2.Year == TheDate.Year)
group a by a.Date1.Date AND by a.Date2.Date into daygroups
select new MyModel{...};
Try removing the 4 extra "where" and change the OR to ||.