I want my query to stop displaying time and just the date. This is what I've tried to far:
Query= (from z in ctx.Interactions
where z.ActivityDate <= StartDateTo
&& z.ActivityDate >= EndDateTo
&& z.Indepth == false
select new
{
Date = new DateTime(z.ActivityDate.Year, z.ActivityDate.Month, z.ActivityDate.Day),
Subject = z.Subject
}).ToList();
And
Query= (from z in ctx.Interactions
where z.ActivityDate <= StartDateTo
&& z.ActivityDate >= EndDateTo
&& z.Indepth == false
select new
{
Date = z.ActivityDate.Date,
Subject = z.Subject
}).ToList();
And both didn't work.
LINQ to Entities does not recognize the method 'System.String ToString(System.String)' method, and this method cannot be translated into a store expression. when trying to apply a string method.
You can use anyDate.ToString("ddMMyyyy");//any preferred format.
Not sure if that is what you are looking for!
Your queries return objects with Date & Subject properties.
In the Date property you are passing a DateTime object. In order to display the short date you have a "ToShortDateString()" function on a date.
If you dont want to work with a date and prefer selecting a string, then do the conversion inside the linq query.
Use this if you want to return strings:
var q = (from z in ctx.Interactions
where z.ActivityDate <= StartDateTo && z.ActivityDate >= EndDateTo && z.Indepth == false
select new { Date = z.ActivityDate.Date.ToShortDateString(), Subject = z.Subject }).ToList();
You would need to perform the formatting at the time of the binding. As you don't show the actual binding code, it is hard to specifically address your situation but lets look at what happens in your query:
Query= (from z in ctx.Interactions
where z.ActivityDate <= StartDateTo && z.ActivityDate >= EndDateTo && z.Indepth == false
select new { Date = z.ActivityDate.Date, Subject = z.Subject }).ToList();
Once LINQ handles this query, the resulting Query variable should be of type List<DateTime>. The way you have the query working you would return a list of DateTimes in a format like this:
2014-04-23 00:00:00
2014-03-28 00:00:00
etc...
In order to bind this without the time value, you need to call ToString() on each element (or the desired element) of the list at the time of binding.
Assuming you are using a ListBox or something similar you could write the following:
foreach (var date in myList) //this is the resultant list from the query
{
listBox1.Items.Add(date.ToString("MM/dd/yyyy");
}
If you are literally binding to a DataSource property, you will need to convert your List<DateTime> to a List<string> with the formatted values.
ToShortDateString() may help you.
Query= (from z in ctx.Interactions
where z.ActivityDate <= StartDateTo
&& z.ActivityDate >= EndDateTo
&& z.Indepth == false
select new
{
Date = z.ActivityDate.ToShortDateString(),
Subject = z.Subject
}).ToList();
convert date into string like below
string stringDate=string.empty;
stringDate=Convert.ToDateTime("2014-04-23 00:00:00").ToShortDateString();
it will give output like
2014-04-23
Related
I'm having an issue with a linq subquery return invalid data when adding in datetime checks as part of the where clause.
This is the original query and it is returning 0; because the result set is null
var subquery =
(from item in g
from e in item.Entry
where e.Type == 1
&& e.EntryType == 2
&& item.StartDate >= priorMonthStartOfDay
&& item.EndDate <= startOfDayQueryParam
select e.Amount).Sum() ?? 0M;
I modified the query to see what the data was; here is that query and the resulting dataset.
var subquery =
(from item in g
from e in item.Entry
where e.Type == 1
&& e.EntryType == 2
select new
{
Amount = e.Amount,
SD = item.StartDate,
ED = item.EndDate,
QD = priorMonthStartOfDay
};
So then I added in the start date comparison and the results are below. The priorMonthStartOfDay is a DateTime with a value of 12/1/2015 12:00:00 AM
var subquery =
(from item in g
from e in item.Entry
where e.Type == 1
&& e.EntryType == 2
&& item.StartDate >= priorMonthStartOfDay
select new
{
Amount = e.Amount,
SD = item.StartDate,
ED = item.EndDate,
QD = priorMonthStartOfDay
};
Why is the date comparison not behaving as I would expected? Given the value of priorMonthStartOfDay, I would expect the result set to be the same for the last two queries. I'm guessing it has something to do with the time equal comparison because if I subtract a second from the priorMonthStartOfDay then the result sets match up again.
The only logical explanation could be that your priorMonthStartOfDay and/or startOfDayQueryParam variables contain time part not shown in the debugger. Note that by default milliseconds part is not shown, not to mention ticks.
To be 100% sure you are comparing against dates, change the date part of the criteria to
&& item.StartDate >= priorMonthStartOfDay.Date
&& item.EndDate <= startOfDayQueryParam.Date
I'm trying to compare dates using Linq to Entities on a SQLite database. The following code works, but I need to trim off the time portion to get the correct results.
return (from c in Context.Car
join d in Context.Driver on c.CarID equals d.DriverID
join r in Context.Rides on c.CarID equals r.RideID into rideJoin
from rides in rideJoin.DefaultIfEmpty()
where c.IsActive && d.IsActive
group rides by new { c.CarID, d.FullName, d.HireDate, d.FirstPayRiseDate } into grp
select new MyCustomClass
{
CarID = grp.Key.CarID,
Driver = grp.Key.FullName,
NumberOfRides = grp.Count(x => x != null && x.RideDate >= grp.Key.HireDate && x.RideDate <= grp.Key.FirstPayRiseDate)
}).OrderBy(x => x.Driver ).ToList();
I've tried using System.Data.Entity.DBFunctions like so and I get this error:
NumberOfRides = grp.Count(x => x != null && DbFunctions.TruncateTime(x.RideDate) >= grp.Key.HireDate && DbFunctions.TruncateTime(x.RideDate) <= grp.Key.FirstPayRiseDate)
SQL logic error or missing database no such function: TruncateTime
I also get the same error with DBFunctions.DiffDays()
I've also tried casting to Date like so and get this error:
NumberOfRides = grp.Count(x => x != null && x.RideDate.Date >= grp.Key.HireDate && x.RideDate.Date <= grp.Key.FirstPayRiseDate)
'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported
What gives? How am I supposed to do Date functions in Linq to Entities with SQLite??
I need to trim off the time portion to get the correct results
No you don't. If you want to include the rows from startDate through endDate inclusive then just use
... && x.RideDate >= startDate && x.RideDate < endDate.AddDays(1)
(Note that the second comparison is now "strictly less than".)
How are you storing dates on the database ? as unix time integrs ?
in that acse you can amend your connection string to include this following config setting and it will make it easy to read the datetime value via EF.
datetimeformat=UnixEpoch;datetimekind=Utc
So something like :
data source="|DataDirectory|\data.sqlite";datetimeformat=UnixEpoch;datetimekind=Utc
Ref: https://stackoverflow.com/a/24323591/3660930
i have linq to entities query below but i want the where clause to use the logic in sample T-SQL code after it.
var myList = from p in ctx.myTable
where !ctx.Report.Any(m => m.ReportDate == DateTime.Today && m.ReportDate == DateTime.Today)
select p;
How can i compare to month and year in my where clause like in the T-SQL below?
WHERE month(R.ReportDate) = month(GETDATE()) AND YEAR(R.ReportDate) = YEAR(GETDATE()))
Dealing with dates in LINQ to Entities is a little tricky. I'm not sure you can generate MONTH() or YEAR() within your SQL. But you can definitely generate DATEPART call with proper m or y as datepart.
Use SqlFunctions.DatePart Method (String, String) to do that:
var todayMonth = DateTime.Today.Month;
var todayYear = DateTime.Today.Year;
var myList = from p in ctx.myTable
where !ctx.Report.Any(m => SqlFunctions.DatePart("m", m.ReportDate) == todayMonth && SqlFunctions.DatePart("y", m.ReportDate) == todayYear)
select p;
Should generate
WHERE DATEPART(m, R.ReportDate) = 2 AND DATEPART(y, R.ReportDate) = 2014)
If you really want the GETDATE() part, you can use following:
var myList = from p in ctx.myTable
where !ctx.Report.Any(m => SqlFunctions.DatePart("m", m.ReportDate) == SqlFunctions.DatePart("m", SqlFunctions.GetDate()) && SqlFunctions.DatePart("y", m.ReportDate) == SqlFunctions.DatePart("y", SqlFunctions.GetDate()))
select p;
Update
I just found that page: CLR Method to Canonical Function Mapping which states, that DateTime.Month and DateTime.Year properties are translated into MONTH and YEAR methods, so following should work just fine:
var myList = from p in ctx.myTable
where !ctx.Report.Any(m => m.ReportDate.Month == SqlFunctions.GetDate().Month && m.ReportDate.Year == SqlFunctions.GetDate().Year)
select p;
A DateTime object has Month and Year property. You can make use of that.
DateTime dateTime = new DateTime();
if (dateTime.Month > DateTime.Today.Month) {
// Do something
}
if (dateTime.Year> DateTime.Today.Year)
{
// Do something
}
Try the Following Since DateTime Contains Year and Month.
where !ctx.Report.Any(m => m.ReportDate.Month == DateTime.Today.Month && m.ReportDate.Year == DateTime.Today.Year)
It compiles normal but when I try to iterate through result of the LINQ query I 've got such exception The group by operation contains an expression that cannot be translated
The query is
var query0 = from c in dc.Prices
where Convert.ToDateTime(c.data).CompareTo(left) >= 0
&& Convert.ToDateTime(c.data).CompareTo(right) <= 0
&& c.idsticker.Equals(x)
group c by new { ((DateTime)c.data).Year, ((DateTime)c.data).Month }
into groupMonthAvg
select new
{
years = groupMonthAvg.Key.Year,
months = groupMonthAvg.Key.Month,
prices = groupMonthAvg.Average(i => i.value)
};
What expression in group by function is wrong?
Try this:
var query0 = from c in dc.Prices
let date = Convert.ToDateTime(c.data)
where date.CompareTo(left) >= 0 && date.CompareTo(right) <= 0 && c.idsticker.Equals(x)
group c by new { date.Year, date.Month } into groupMonthAvg
select new
{
years = groupMonthAvg.Key.Year,
months = groupMonthAvg.Key.Month,
prices = groupMonthAvg.Average(i => i.value)
};
I'm guessing this is because the data column in Price is a String or some other type other than DateTime.
Try changing the (DateTime)c.data) cast to a Convert.ToDateTime(c.data) instead.
I am not sure if the Linq-SQL translator supports casts.
If possible change the underlying data type in the database to a DateTime if it stores a Date Time value.
I am using dynamic Linq to return data for user-input search criteria. My query is working fine except for the user selected dates. My current code is:
StringBuilder whereClause = new StringBuilder();
if (startDate.HasValue || endDate.HasValue)
{
DateTime searchStartDate = startDate.HasValue ? startDate.Value : DateTime.MinValue;
DateTime searchEndDate = endDate.HasValue ? endDate.Value : DateTime.MaxValue;
whereClause.AppendFormat("Date >= {0} && Date <= {1}",
searchStartDate.Date.ToUniversalTime(),
searchEndDate.Date.ToUniversalTime());
}
if (whereClause.Length > 0)
{
return (from p in this.repository.GetQueryable<Party>() select p)
.Where(whereClause.ToString())
.ToList();
}
The query falls over because the comparison is being done between a DateTime field and a Int32 field, meaning the query has interpreted my date literals as integers.
How should I be formatting the dates?
Use
.Where("Date >= #0 && Date <= #1",
searchStartDate.Date.ToUniversalTime(),
searchEndDate.Date.ToUniversalTime())
instead.
In reply to Val's comment:
OK, then you can do:
whereClause.AppendFormat("Date.ToString() >= \"{0}\" && Date.ToString() <= \"{1}\"",
searchStartDate.Date.ToUniversalTime(),
searchEndDate.Date.ToUniversalTime());
You have to convert the Date in the query to a string and then compare it a quoted string literal. Without the quotes the parser is inerpreting the numbers inserted into the where clause as integers - what should explain the error you originally got.
Why are you parsing strings in a LINQ expression? The entire point of LINQ is to avoid that.
var q = from p in this.repository.GetQueryable<Party>() select p;
if (startDate.HasValue || endDate.HasValue)
{
var searchStartDate = startDate.HasValue ? startDate.Value : DateTime.MinValue;
var searchEndDate = endDate.HasValue ? endDate.Value : DateTime.MaxValue;
return
q.Where (p=> p.Date >= searchStartDate.ToUniversalTime()
&& p.Date <= searchEndDate.ToUniversalTime()).ToList();
}
return q.ToList();
UPDATE:
In response to comments: I'm building that one at run-time. The question isn't run-time vs compile-time; it's "in strings" vs "in code". StringBuilder lets you append text; LINQ lets to chain lamdbas. It all works out the same --- except your code is type-safe and syntax checked using lambdas.
To demostrate this concept further, the following code compiles & runs fine, and allows to you to change the Where clause based on the values of oddsOnly and lowerLimit.
int[] nums = {1,2,3,4,5,6,7,8,9,10};
bool oddsOnly = true;
bool lowerLimit = 5;
var q = from i in nums select i;
if (oddsOnly)
q = q.Where( n=> n%2 == 1);
if (lowerLimit != 0)
q = q.Where( n=> n >= lowerLimit);
foreach(var i in q)
Console.WriteLine(i);
Depending on how you set those values, it will use zero, one or both of the where clauses.
The Dynamic LINQ string would need to look something like:
"Date >= DateTime(2015, 10, 21)"
This is mentioned in the documentation in the DynamicQuery project in the download mentioned at http://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library.
Note, there isn't a new before the DateTime constructor.
I tried this and it works. I'm using Telerik's RadGrid control for ASP.NET AJAX. The grid builds the filter string and I needed to add the filter to my query to get the filter to execute in the database using LINQ to Entities. The problem is that the generated filter needed to be altered a little for it to work with LINQ to Entities as opposed to LINQ to Objects. It was doing a DateTime.Parse() which isn't supported in LINQ to Entities.