casting to datetime data to month and year in C# - c#

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)

Related

how to convert string to datetime in Linq where clause

DateTime newDate = DateTime.Now.AddDays(-30);
var queryResultPage = (from r in CustomPlanning
where (r.Assignment == "In Use") &&
(r.CUST_SHRT_NM != null) &&
System.Convert.ToDateTime(r.lastlogontimestamp) < newDate &&
!(from uA in SurveyActivity
where uA.CustomDemandID == r.ID
select uA.CustomDemandID).Contains(r.ID)
select r)
.OrderBy(t => t.ID);
Above is my code. lastlogontimestamp is a string field in my table. i need to do this check to show the query result in a grid. Can someone please help?
ok i tried this and it worked
DateTime newDate = DateTime.Now.AddDays(-30);
var queryResultPage = (from r in CustomPlanning
where (r.Assignment == "In Use") && (r.lastlogontimestamp != null && r.lastlogontimestamp != string.Empty)
&& (r.CUST_SHRT_NM != null)
&& !(from uA in SurveyActivity where uA.CustomDemandID == r.ID select uA.CustomDemandID).Contains(r.ID)
select r).OrderBy(t => t.ID).ToList();
queryResultPage = queryResultPage.Where(r => System.Convert.ToDateTime(r.lastlogontimestamp) < newDate).ToList();
You cannot in this query directly. You need to materialize the results from the query in a list, and run another query to filter the returned CustomPlanning with Linq-To-Objects (it supports conversion).
You can convert newDate to string
string newDate = DateTime.Now.AddDays(-30).ToString();
and try to compare strings instead, but you need to cover lots and lots of cases, so it is not recommended. You can consider changing the type of lastlogontimestamp to DateTime, when you have dates, it is natural to store them as dates.

LINQ not returning the right ROW of data

This is my full set of data, and the highlighted row should be returned by my query but its not returning any data.
http://screencast.com/t/S0DgVgIuQS
and the linq is like this
if (filtro.Equals("Pendientes"))
{
var activididadesFiltradas = actividades
.Where(p => (Convert.ToDateTime(p.fechaVencimiento) >= DateTime.Today)
&& (Convert.ToDateTime(p.fechaVencimiento) <= DateTime.Today.AddDays(7))
&& (p.estado != "Documentada")).ToList();
return activididadesFiltradas;
}
basically it should return data where fechavencimiento is between today and 7 days in the future, and estado different to Documentada, if you see the screenshot, the conditions are met.
btw, the dataset has the dates in string, so I have to convert them before comparing
Upodate1
I also tried this but no results
var present = DateTime.Today;
var future = DateTime.Today.AddDays(7);
var validIDs = actividades
.Select(s => new
{
id = s.ID,
filter = s.fechaVencimiento,
date = Convert.ToDateTime(s.fechaVencimiento, CultureInfo.InvariantCulture ),
present = new DateTime(present.Year, present.Month, present.Day),
future = new DateTime(future.Year, future.Month, future.Day)
})
.Where(m => (m.date - m.present).TotalDays >= 0 && (m.future - m.date).TotalDays >= 0 && !m.filter.Equals("Documentada"))
.Select(s => s.id);
var activididadesFiltradas = actividades.Where(a => validIDs.Contains(a.ID)).ToList();
Update 2
This is the record that should be returned:
http://screencast.com/t/1SUjRV2rVGa
`"(Convert.ToDateTime(p.fechaVencimiento) >= DateTime.Today)"`
7/09/2015 is definitely not >= today (in MM/dd/yyyy) format
Your comparisons don't take the time component into account. Even if your date is parsed correctly, if it doesn't contain a time element in the string representation, you might end up in a situation where your date is 2015/01/01 00:00:00:000 and 'today' is 2015/01/01 03:12:56:001. Seeing that you're only interested in days, I would suggest 'normalising' your dates first and then filtering based on the result.
Possibly something like this:
var format = "dd/MM/yyyy";
var present = DateTime.ParseExact (DateTime.Today.ToString(format, CultureInfo.InvariantCulture), format, CultureInfo.InvariantCulture);
var future = DateTime.ParseExact (DateTime.Today.AddDays (7).ToString(format, CultureInfo.InvariantCulture), format, CultureInfo.InvariantCulture);
var activididadesFiltradas = actividades
.Where(p => ((DateTime.ParseExact(p.fechaVencimiento, format, CultureInfo.InvariantCulture) - present).TotalDays >= 0)
&& (future - DateTime.ParseExact(p.fechaVencimiento, format, CultureInfo.InvariantCulture)).TotalDays >= 0
&& (p.estado != "Documentada")).ToList();
return activididadesFiltradas;

Short Date in Linq

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

LINQ Group By with subquery

I am trying to make a query on LINQ using a GroupBy, where on the Select statement I try to make some kind of subquery. The idea is that I have 7 days to look for, I need to get the average value of these last 7 days but also the current value for the current day. So I have tried the following code:
var oDate = DateTime.UtcNow;
var startDate = oDate.AddWorkingDays(-7);
var endDate = oDate.AddWorkingDays(-1);
var races = RaceTimes.Where(
x =>
x.ODate >= startDate && x.ODate <= oDate && x.Status == "Finished")
.GroupBy(x => x.Athletes.Name).Select(x => new
{
Name = x.Key,
Description = "Just a Random Description for now",
ODate = oDate,
SevenDaysAvg = (int?)x.Where(y => y.ODate >= startDate && y.ODate <= endDate).Average(y => SqlFunctions.DateDiff("s", y.StartTime, y.EndTime)),
RaceTime = (int?)x.Where(y => y.ODate == oDate).Average(y => SqlFunctions.DateDiff("s", y.StartTime, y.EndTime))
}).ToList().Where(x => x.RaceTime!= null).ToList();
The SevenDaysAvg (average) works fine, it returns me the average of the last 7 days races. However, Latency is always returning me null.
I am trying to make the translation of my query from SQL, which works fine:
...
AVG(case when h.ODate BETWEEN '20140219' AND '20140227' then DATEDIFF(SECOND, h.StartTime, h.EndTime) else null end) AS SevenDaysAvg,
AVG(case when h.ODate = '20140227' then DATEDIFF(SECOND, h.StartTime, h.EndTime) else null end) AS RaceTime,
...
So what am I doing wrong in my LINQ query? This what I am doing is not possible? I've also tried another aproach. First calculate all averages, and then in the main query have something like:
SevenDaysAvg = averages.Where(y => y.Name== x.Athletes.Name).Select(y => y.SevenDaysAvg).FirstOrDefault()
Once again, this approach didnt work, it keeps giving me empty results. Whats wrong here?

The group by operation contains an expression that cannot be translated

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.

Categories