I've a IQueryable result queried from the db using LINQ, now I had to filter all the rows based on a field date_sent. No. of days should be calculated from date_sent to current date. this total no. of days that falls undet 0 to 30 days range should be retrieved. How do I do it. I have the below code but it's not working. no errors but does not filter properly.
query = query.Where(x => x.DATE_SENT != null);
query = query.Where(x => (int)(EntityFunctions.DiffDays(currentDate, (DateTime)x.DATE_SENT)) >= 0 &&
(int)(EntityFunctions.DiffDays(currentDate, (DateTime)x.DATE_SENT)) <= 30);
Any guidance on how it can be handled will be great.
You can get it using this query.
var dtDiff = DateTime.Now.AddDays(-30);
query = query.Where(z=> z.DATE_SENT >= dtDiff);
31-60 days
var dtDiff31 =DateTime.Now.AddDays(-31);
var dtDiff60 =DateTime.Now.AddDays(-60);
query = query.Where(z=> z.DATE_SENT >= dtDiff60 && z.DATE_SENT <= dtDiff31 );
It seems you just want to filter by a range of dates:
DateTime filterDate = currentDate.AddDays(-30);
query = query.Where(x => x.DATE_SENT >= filterDate);
In case your currentDate can vary you add the second condition:
query = query.Where(x => x.DATE_SENT >= filterDate && x.DATE_SENT < currentDate);
Related
I have a snapshot table in my database that holds historical data of appointment availability.
I'm trying to write a LINQ query to get the total number of AvailableSlots within a given date range from the latest snapshot.
Here is what my table looks like:
So with this given data, I'd want my LINQ query to return the sum of AvailableSlots within the date range of 2018-01-01 - 2018-01-02 and with the latest SnapShotTime. So, I'd expect the query to return 4.
Here is what I have so far.
var test = db.snapshots
.GroupBy(g =>
g.AppointmentTime >= startDate &&
g.AppointmentTime <= endDate
).Select(s => s.OrderByDesending(x => x.SnapShotTime).FirstOrDefault();
However, I'm not sure how to put the Sum of available slots into this LINQ query. Any help on writing this query would be appreciated!
i dont see exactly the query that you wrote do, but based on your explanation i think sth like this might have work
var query=db.snapshots
.Where(x=>x.AppointmentTime >= startDate &&
x.AppointmentTime <= endDate)
.GroupBy(x=>x.SnapShotTime)
.OrderByDesending(g=>g.Key)
.Take(1)
.Sum(x=>x.Value.AvailableSlots);
or if it seems so complicated you better first get the latest date like this
var latest=db.snapshots
.OrderByDesending(x => x.SnapShotTime)
.FirstOrDefault().SnapShotTime;
and then get your count like this
var query=db.snapshots
.Where(x=>x.AppointmentTime >= startDate &&
x.AppointmentTime <= endDate &&
x.SnapShotTime==latest)
.Sum(x=>x.AvailableSlots);
Here is what I did.
static void Main(string[] args)
{
DateTime startDate = new DateTime();
DateTime endDate = new DateTime();
List<FakeAppointments> appointmentsFromDatabase = new List<FakeAppointments>();
var appointmentsBetweenStartDateAndEndDate = appointmentsFromDatabase.Where(p => p.SnapshotTime >= startDate && p.SnapshotTime <= endDate).ToList();
int sum = appointmentsBetweenStartDateAndEndDate.Sum(p => p.AvailableSlots);
Console.ReadKey();
}
public class FakeAppointments
{
public DateTime SnapshotTime;
public int AvailableSlots;
}
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 have a problem; actually I am having workingHours in my database table in the format HH.mm and I want to sum all the working hours using LINQ can any 1 please tell how to do this.
In totalWeekHours I have all the working hours and I have replace HH.mm format in HH:mm but I don't know how to parse it in timespan and then Sum() using Linq.
please help.
var totalWeekHours = (from twh in db.MytimeMaster
where ((twh.date >= lstsun && twh.date <= tilldate)
&& (twh.agentID == agentid))
select twh.totalworkinghours).ToList();
if (totalWeekHours.Count > 0)
{
List cnvrtToTimespanlist = new List();
foreach(var list in totalWeekHours)
{
cnvrtToTimespanlist.Add(list.ToString().Replace('.', ':'));
}
}
You can use Aggregate method.
var sum = (from twh in db.MytimeMaster
where ((twh.date >= lstsun && twh.date <= tilldate) && (twh.agentID == agentid))
select twh.totalworkinghours).Aggregate(TimeSpan.FromMinutes(0), (total, next) => total + next);
p.s. assume used TimeSpan for time intervals.
How do I return a list of dates to the nearest minute. I need the linq query to return only dates the match the passed date to the nearest 3 minutes
return EntitySet.Count(f => f.VISITDATE == dt.Date);
I use the code like this usually:
if((date2 - date1).Minutes <= 3) {
Console.WriteLine("Do not add again!!");
}
var dates = (from ES in EntitySet
where ES.VISITDATE >= dt.Date.AddMinutes(-3) && ES.VISITDATE <= dt.Date.AddMinutes(3)
select ES.VISITDATE)
var result = EntitySet.Where(item => Math.Abs((item.VISITDATE - dt.Date).TotalMinutes) <= 3);
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.