I want to fetch values from database with specific intervals in C# and need a LINQ query for that.
This is what my database looks like
Id SensorId Value CreatedOn
1 8 33.5 15-11-2012 5:48 PM
2 5 49.2 15-11-2012 5:48 PM
3 8 33.2 15-11-2012 5:49 PM
4 5 48.5 15-11-2012 5:49 PM
5 8 31.8 15-11-2012 5:50 PM
6 5 42.5 15-11-2012 5:50 PM
7 8 36.5 15-11-2012 5:51 PM
8 5 46.5 15-11-2012 5:51 PM
9 8 39.2 15-11-2012 5:52 PM
10 5 44.4 15-11-2012 5:52 PM
11 8 36.5 15-11-2012 5:53 PM
12 5 46.5 15-11-2012 5:53 PM
13 8 39.2 15-11-2012 5:54 PM
14 5 44.4 15-11-2012 5:54 PM
.. . .... ...................
The interval is in minutes.
So, if the interval is 10 minutes, then we need the values at 5:48, 5:58, 6:08 and so on...
This is what I have tried
while (startDateTime <= endDateTime)
{
var fetchIndex =
fullValues.Where(
item =>
item.CreatedOn >= startDateTime &&
item.CreatedOn < startDateTime.AddMinutes(1)).Select(
item => item.FetchIndex).FirstOrDefault();
if (fetchIndex != 0)
{
var temp = fullValues.Where(item => item.FetchIndex == fetchIndex).ToList();
result = result.Union(temp);
}
startDateTime = startDateTime.AddMinutes(interval);
}
Since the while loop iterates through the table, it takes a lot of time to get these values.
Is there any way of getting the data in a single query?
from x in table
where x.CreatedOn >= startDateTime &&
x.CreatedOn <= endDateTime &&
(x.CreatedOn.Minute % 10) == 0
select x
this will give you 1:00,1:10,1:20
The 10 represents your interval and 0 is your offset.
Following approach creates a list requiredTimes which holds all of the relevant datetimes between startDateTime and endDateTime (datetimes in 10 minute intervals between start and end datetimes).
After such list is created the fullValues is inner joined on it. The result is an IEnumerable with datetimes from fullValues that satisfy the interval condition. It should work fast since creating such list is quick and the Join method is an inner join which should also work fast, try it:
DateTime startDateTime = DateTime.Parse("15-11-2012 5:48 PM");
DateTime endDateTime = DateTime.Parse("16-11-2012 5:58 PM");
List<DateTime> requiredTimes = new List<DateTime>();
DateTime dt = startDateTime;
requiredTimes.Add(dt);
while (dt <= endDateTime)
{
dt = dt.AddMinutes(10);
requiredTimes.Add(dt);
}
var result = fullValues.Join(
requiredTimes,
fv => fv.CreatedOn,
rt => rt,
(fv, rt) => fv);
Related
i want to fetch records between time 8 pm to 6 am . how to write where clause to get the records between 8 pm and 6 am only.
Code
model = model.OrderByDescending(x => DateTime.Parse(x.UpdatedTime)).Where(x=>x.status=="UP").Take(100).ToList();
sample data
1 39 6/28/2017 12:08:43 PM UP
2 39 6/28/2017 12:04:18 PM UP
3 39 6/28/2017 11:49:45 AM UP
data type
public string UpdatedTime { get; set; }
controller
binModel.UpdatedTime = TimeZoneInfo.ConvertTimeFromUtc(item.timestamp, TimeZoneInfo.FindSystemTimeZoneById("India Standard Time")).ToString();
model = model.Where(x=> {
var timeOfDay = DateTime.Parse(x.UpdatedTime).TimeOfDay;
return x.status=="UP" &&
(timeOfDay.TotalHours >= 20 || timeOfDay.TotalHours < 6);
})
.OrderByDescending(x => DateTime.Parse(x.UpdatedTime)).Take(100).ToList();
should verify that the time is on or after 8pm, and prior to 6am.
Check the DateTime.Hour is more than 8pm or less that 6 AM
model = model.OrderByDescending(x => DateTime.Parse(x.UpdatedTime)).Where(x=>x.status=="UP" && (UpdatedTime.Hour > 20 || UpdatedTime.Hour < 6)).Take(100).ToList();
If a user selects 07-07-2016, I want to count how many times billdays > 30 for that billdate month, for the past 12 months.
Query is this:
select COUNT(*) as 'BillsOver30' from pssuite_web.pujhaccd
where billdays>30 and DATEDIFF(month,'07-07-2016', GETDATE()) <= 13
Group By Month(billdate)
Result is this:
1784 (July)
1509 (June)
2986 (May)
2196 (etc)
5853
3994
1753
1954
869
1932
629
1673
LINQ query is:
DateStart = '07-07-2016' (from a textbox on view)
DateTime earliestDate = objdate1.DateStart.Value.AddMonths(-13);
var custQuery9 = (from m in DataContext.pujhaccds
where m.billdays > 30 &&
m.billdate >= earliestDate &&
m.billdate <= objdate1.DateStart
group m by m.billdate.Value.Month into p
select new Date1()
{
theMonth = p.Key,
theCount = p.Count()
});
Results are:
Month Count
1 1029
2 1018
3 1972
4 1519
5 2657
6 2019
7 1206
8 1023
9 761
10 1620
11 354
12 931
You can see that the LINQ query is way off.
Doesn't matter what date I put in, the result always stays the same. Rather than 12 months from starting date.
I must be writing it wrong, thanks.
I'm using LINQ for getting list of objects which are in a specific date range. For example, I have current day in DateTime format: 21.05.2016 0:00:00 and I need to get news which were published after 1 day ago (5 day ago, 3 months ago, 1 year ago, 5 years ago) and until this moment. I did it the folowing way:
List<MyObject> data =
DataDownloader.myList.Where(s => s.Date.Year >= fromDate.Year
&& s.Date.Month >= fromDate.Month
&& s.Date.Day >= fromDate.Day
&& s.Date.Year <= toDate.Year
&& s.Date.Month <= toDate.Month
&& s.Date.Day <= toDate.Day).ToList();
toDate is my current date. I find the fromDate by the following:
1 day:
fromDate = toDate;
5 days:
fromDate = toDate.AddDays(-5);
3 months:
fromDate = toDate.AddMonths(-3);
etc.
But I get only 2 news for 3 months. It's 21.04.2016 0:00:00 and 21.05.2016 0:00:00. So you know they differ only numbers of months because my current date is 21.05.2016. What's I do wrong? I should get much more news I know it.
You're comparing each of the elements of a date, which isn't going to give you the right answer.
You're saying for the 'last 3 months' (from 21/02/2016 to 21/05/2016) that the day has to be between 21 and 21, the month between 2 and 5 and the year between 2016 and 2016
You're effectively searching for 21/02/2016, 21/03/2016, 21/04/2016 or 21/05/2016 rather than all dates between.
Just compare the date:
list.Where(x => x.Date >= fromDate && x.Date <= toDate).ToList();
I'm using C# and SQL Server 2008 R2.
I have hour data like this:
Client_ID TheHour HourMin HourMAx
53026 09:00 7 9
53026 12:00 10 12
53026 15:00 13 15
53026 18:00 16 19
I will put TheHour into my combobox, that depends on computer hour.
When the computer hour is 10:00 then the value of my combobox:
12:00
15:00
18:00
09:00
My linq is :
int The_Hour = DateTime.Now.Hour;
var query = from o in oEntite_T.LS_CLIENTHORRAIRE
where o.CLIENT_ID == CLIENT_ID &&
The_Hour >= o.HEURE_MIN && The_Hour <= o.HEURE_MAX
select o;
LesListe = query.ToList();
It return only 1 value, which is 12:00.
That meant my combobox will select hour that depend on computer hour, but it leave the possibility for the user to select another hour.
Here is a working example in LINQPad, I also added a flag to indicate selected value.:
void Main()
{
var LS_CLIENTHORRAIREs = new List<LS_CLIENTHORRAIRE>
{
new LS_CLIENTHORRAIRE{TheHour="09:00",HourMin=7,HourMAx=9},
new LS_CLIENTHORRAIRE{TheHour="12:00",HourMin=10,HourMAx=12},
new LS_CLIENTHORRAIRE{TheHour="15:00",HourMin=13,HourMAx=15},
new LS_CLIENTHORRAIRE{TheHour="18:00",HourMin=16,HourMAx=19}
};
LS_CLIENTHORRAIREs.Dump();
int The_Hour = 10;
var query = from o in LS_CLIENTHORRAIREs
select new {o.TheHour,o.HourMin,o.HourMAx,selected = The_Hour >= o.HourMin && The_Hour <= o.HourMAx}
;
query.OrderBy (q => q.HourMAx>The_Hour ? 0 : 1).ThenBy (q => q.HourMAx).Dump();
}
public class LS_CLIENTHORRAIRE
{
public string TheHour{get;set;}
public int HourMin{get;set;}
public int HourMAx{get;set;}
}
Results
So, basically, you don't want to filter the list, you want to sort it, right?
First, you want to sort it by
whether the MaxHour is in the past
and then by
TheHour itself.
Example: Let's assume it is 10:00:
Client_ID TheHour HourMin HourMax MaxHourIsInThePast
53026 09:00 7 9 x
53026 12:00 10 12
53026 15:00 13 15
53026 18:00 16 19
Now you return a list that orders first by MaxHourIsInThePast (first those without x and then those with x) and then by TheHour.
Implementation is left as an exercise. Hint: You will need the LINQ order by keyword, and an expression similar to (o.HourMax < currentHour ? 2 : 1) will come in handy.
Let assume the computer hour is 10.
Then: your condition would be: HourMin <= 10 && HoureMax >= 10.
The first condition would return row 1 and 2. The second one would return row 2. The intersect will return only the second row, which is 12:00.
If you want to get all rows, just remove these conditions.
I'm trying to call something every 3 months (quarterly) in Quartz.NET (using both stable and latest version 2 which is beta with same results).
I create cron trigger with 0 30 8 3 */3 ? * to be called every 3 months at 8.30am on third of the month it occurs.
So technically since its 2 of September today I would expect it to trigger tomorrow. However it next run time shows as being next month. Why is that so?
Updated: As per answers I got I created following method - could be useful for someone:
public static string CalculateMonthsWithInterval(int startMonth, int interval)
{
var months = new List<string>();
var monthNames = new [] {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
var monthSelector = startMonth % interval;
for (var i = 0; i < 12; i++)
{
if (i % interval == monthSelector)
{
months.Add(monthNames[i]);
}
}
return string.Join(",", months.ToArray());
}
Ps: I didn't use indexes for months because for some reason it wasn't working well with my Quartz (v2 BETA). Also its easier to read in DB level.
Example call - Every 3 months based on startDate:
var cronMonths = CronUtils.CalculateMonthsWithInterval((startDate.Month - 1), 3);
Well I think that's because the scheduler will verify which month can be divided by 3, since all month in Quartz are based 0 (according to: http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-06), the month that will be scheduled will be january, april, july and october.
0 mod 3 = 0 -> JAN
1 mod 3 = 1 -> FEB
...
8 mod 3 = 2 -> SEP
9 mod 3 = 0 -> OCT
The Quartz scheduler will analyse your cron expression and keep only those where their modulus 3 equals to 0.
If you want it to be 1 month before that (march, june, september and october) you will have to set it to:
0 30 8 3 MAR,JUN,SEP,DEC ? *
A good page to create cron expressions: http://www.cronmaker.com/
Cron format:
0 0 12 1 1/3 ? *
Executes every:
1. Saturday, April 1, 2017 12:00 PM
2. Saturday, July 1, 2017 12:00 PM
3. Sunday, October 1, 2017 12:00 PM
4. Monday, January 1, 2018 12:00 PM
5. Sunday, April 1, 2018 12:00 PM