Entity framework and datetime compare - linq

Is possible to create linq query to find all records, which are in date range?
For example :
I have table with VacationStart, VacationEnd - both datetime and i need find all pending vacations to current date.
I am trying
context.Vacations..Where(x=> x.VacationStart >= DateTime.Now && x.VacationEnd < DateTime.Now)
but i getting 0 records...
Sample data 2011-10-27 08:30:00.000 2011-10-28 17:00:00.000
Current date : 2011-10-26 23:39:46.297
Where i do mistake?
Thanks

You are asking for vacations that start after NOW and end before NOW, Impossible. try asking and comparing a start time and end time that are different and where start time is less than the end time.
Gives only the vacations currently in progress.
var query = context.Vacations.Where(v => v.VacationEnd > DateTime.Now
&& v.VacationStart < DateTime.Now);
Gives vacations that haven not begun yet.
var query = context.Vacations.Where(v => v.VacationStart > DateTime.Now);
Gives Vacations that are in progress or still have not started.
var query = context.Vacations.Where(v => v.VacationEnd > DateTime.Now);
The last one doesn't filter any future vacations.

Related

How to make zero counts show in LINQ query when getting daily counts?

I have a database table with a datetime column and I simply want to count how many records per day going back 3 months. I am currently using this query:
var minDate = DateTime.Now.AddMonths(-3);
var stats = from t in TestStats
where t.Date > minDate
group t by EntityFunctions.TruncateTime(t.Date) into g
orderby g.Key
select new
{
date = g.Key,
count = g.Count()
};
That works fine, but the problem is that if there are no records for a day then that day is not in the results at all. For example:
3/21/2008 = 5
3/22/2008 = 2
3/24/2008 = 7
In that short example I want to make 3/23/2008 = 0. In the real query all zeros should show between 3 months ago and today.
Fabricating missing data is not straightforward in SQL. I would recommend getting the data that is in SQL, then joining it to an in-memory list of all relevant dates:
var stats = (from t in TestStats
where t.Date > minDate
group t by EntityFunctions.TruncateTime(t.Date) into g
orderby g.Key
select new
{
date = g.Key,
count = g.Count()
}).ToList(); // hydrate so we only query the DB once
var firstDate = stats.Min(s => s.date);
var lastDate = stats.Max(s => s.date);
var allDates = Enumerable.Range(1,(lastDate - firstDate).Days)
.Select(i => firstDate.AddDays(i-1));
stats = (from d in allDates
join s in stats
on d equals s.date into dates
from ds in dates.DefaultIfEmpty()
select new {
date = d,
count = ds == null ? 0 : ds.count
}).ToList();
You could also get a list of dates not in the data and concatenate them.
I agree with #D Stanley's answer but want to throw an additional consideration into the mix. What are you doing with this data? Is it getting processed by the caller? Is it rendered in a UI? Is it getting transferred over a network?
Consider the size of the data. Why do you need to have the gaps filled in? If it is known to be returning over a network for instance, I'd advise against filling in the gaps. All you're doing is increasing the data size. This has to be serialised, transferred, then deserialised.
If you are going to loop the data to render in a UI, then why do you need the gaps? Why not implement the loop from min date to max date (like D Stanley's join) then place a default when no value is found.
If you ARE transferring over a network and you still NEED a single collection, consider applying D Stanley's resolution on the other side of the wire.
Just things to consider...

How to compare a date in ruby?

I am running a SQL query which returns some orders each having a date. I want to check which orders were made on current date ?
I am able to do so by:
orders = Order.find_by_sql(query).reject {|o|
today = Time.now
end_of_today = Time.local(today.year, today.month, today.day, 23, 59, 59)
start_of_today = Time.local(today.year, today.month, today.day, 00,00,00 )
o.date > end_of_today
o.date < start_of_today
}.sort_by {|o|
o.delivery_date
}
'orders' contain all the orders which were made at any time Today.
Is there a simpler way of doing this in ruby ?
To get the orders made on the current date, you can do the following:
orders = Order.where("date >= ?", Time.zone.now.beginning_of_day).order(:delivery_date)
Hope this helps!
use DateTime.now.beginning_of_day
Order.where('date >= ?', DateTime.now.beginning_of_day).order(:delivery_date)
I think you are looking for this, it will cover all orders for today
orders = Order.where("created_at <= ? AND created_at >= ?", Time.zone.now.end_of_day, Time.zone.now.beginning_of_day).order(:delivery_date)
Now you are getting all the orders from the database (depends on what string is in the query) and then filtering the array, which is not the most efficient way if you have a large database. Much better way is doing this on SQL side.
Just use pure string conditions:
# Or set it to any other date in the past
target_date = Time.zone.now
orders = Order.find_by_sql(query)
.where("date >= ?", target_date.beginning_of_day)
.where("date <= ?", target_date.end_of_day)
.order(:delivery_date)
More details here: http://guides.rubyonrails.org/active_record_querying.html#pure-string-conditions
More info on Active Support DateTime methods: http://api.rubyonrails.org/classes/DateTime.html#method-i-beginning_of_day

multiple group by using linq

I need return just 2 lines in my query. One line with a string Today and a number of cases closed today, on my second line I need a string Last Week and a number of cases closed on the last week.
How I group with a range date?
Sum Name
----------- ----------
12 Today
33 Last Weeb
How about this:
var caseCounts = Cases
.Where(c => c.Date == today || (c.Date >= startOfLastWeek && c.Date <= endOfLastWeek))
.GroupBy(c => c.Date == today ? "Today" : "Last Week")
.Select(g => new {
Name = g.Key, Sum = g.Count()
});
You would need to define the 3 dates (today, startOfLastWeek, endOfLastWeek) before hand, but it gives you the results you are after.
GROUP BY YEARWEEK(date) should work. Depending on your dbms, you might be able to use another function, or program your own.
http://www.tutorialspoint.com/sql/sql-date-functions.htm#function_yearweek

Filtering by Date (linq)

I have DateTime field named "repeat" in database. I want to take only records which Date in "repeat" is today.
I tried :
(...).Where(e => e.repeat.Value.Date.Day.Equals(DateTime.Now.Day));
or:
(...).Where(e => e.repeat.Value.Date.Day==DateTime.Now.Day);
but it doesn't work.
Any ideas?
Thanks,Kamil
"It doesn't work" is pretty vague, but currently you're checking the day of the week rather than the date. I would suggest using:
Date today = DateTime.Today;
var query = ....Where(e => e.repeat.Value.Date == today);
EDIT: It's not clear what the types involved here are - if repeat.Value is not itself a DateTime, you may want:
var query = ....Where(e => e.repeat.Value.Date.Date == today);
Give this a try:
(...).Where(e => (e.repeat >= DateTime.Today) && (e.repeat < DateTime.Today.AddDays(1)))
Compare short date ensures you the year/month/day are the same in one shot :
(...).Where(e => e.repeat.Value.Date.ToShortDateString() == DateTime.Now.ToShortDateString());
Expert Solution is: Use DbFunctions.CreateDateTime() in Linq Query.
var date = DateTime.Now.AddDays(-1).Date;
var actions = await _context.Set<Your_table>()
.AsNoTracking()
.Where(x => DbFunctions.CreateDateTime(x.YourColumn.Value.Year, x.YourColumn.Value.Month, x.YourColumn.Value.Day, 0, 0, 0) == date)
.ToListAsync();

Compare only Date in nHibernate Linq on a DateTime value

I trying to compare two dates (DateTime) in nHibernate linq:
query = query.Where(l => (l.datCriacao.Date == dtLote.Date)
but I am getting the error:
NHibernate.QueryException: could not resolve property: datCriacao.Date of: SAGP.Entities.Lote
Anyone knows how I can solve this? Thanks
I solved the problem doing a between with the dates:
DateTime initialDate, finalDate;
initialDate= DateEntity.Date;
finalDate= new DateTime(DateEntity.Year, DateEntity.Month, DateEntity.Day, 23, 59, 59);
query = query.Where(l => (((l.dateEntity>= initialDate) && (l.dateEntity<= finalDate))
This is super old, but I'd add to jaspion's example as:
query = query.Where(l => (l.datCriacao >= dtLote.Date && l.datCriacao < dtLote.Date.AddDays(1))
You can check the condition like this
var nextDay = DateTime.Today.AddDays(1);
query = query.Where(l => (l.datCriacao >= dtLote && l.datCriacao < nextDay);
here you'll get the records on dtLote date as we checking between dtLote and dtLote+1 day (00:00:00) we'll get today's date record only what ever may be the time...

Resources