I get the data returned of the selected date range which is between the range or isnt. but not if the startDate and endDate is the same. Like example: from 14.10.2017 - 14.10.2017. It returns me then no data (but it should because 5 database records are affected)
foreach (Content content in db.Contents)
{
if (content.ShippedDate < startDate || content.ShippedDate > endDate)
}
Anyone has a solution?
You should update the condition to include the same date.
1.1.2016 < 1.1.2016 //FALSE
1.1.2016 <= 1.1.2016 //TRUE
Adjusting conditions:
content.ShippedDate <= startDate
content.ShippedDate >= endDate
Code:
foreach (Content content in db.Contents)
{
if (content.ShippedDate <= startDate || content.ShippedDate >= endDate)
//the code here
}
use <= (smaller than or equal) and >= (greater than or equal) instead of < and >, this will match values that are equal as well rather than just the ones that are smaller or greater than given value.
Also please refer to this page to learn more about c# operators as this is a very basic questions
https://msdn.microsoft.com/en-us/library/6a71f45d.aspx
Related
I have the following code, and I am planning to use it to check if the user has placed a correct number of days between two datetimepickers.
I've searched on google, and some posts say use var, some say parse, and still it wont work, the message box won't pop up upon checking.
I have already made it work by using a label as a container of the result and use an if else statement to check if the text is equal to 14,15 or 16. It works cause i only need to detect if its 14, 15 or 16, but what if i was given a situation where i need to compare large numbers, I wish I a better solution than what i have right now.
Can someone please tell me how to compare time spans in an if else statement properly? Thank you so much. have a nice day :)
DateTime dateFrom = from_dtPicker.Value;
DateTime dateTo = to_dtPicker.Value;
TimeSpan DayDifference = dateTo - dateFrom;
double NumberOfDays = DayDifference.TotalDays;
if ((NumberOfDays < 14) && (NumberOfDays > 16))
{
//message box
}
Here's what i mean with my weird solution though,
DateTime dateFrom = pp_from_dtPicker.Value;
DateTime dateTo = pp_to_dtPicker.Value;
TimeSpan DayDifference = dateTo - dateFrom;
numofdaysLBL.Text = DayDifference.TotalDays.ToString();
if ((numofdaysLBL.Text != "14") && (numofdaysLBL.Text != "15") && (numofdaysLBL.Text != "16"))
{
//msgbox
}
It seems to me, that your comparison is the problem here
if ((NumberOfDays < 14) && (NumberOfDays > 16))
NumberOfDays can never be less than 14 AND more than 16 at the same time. Instead invert the comparison:
if ((NumberOfDays >= 14) && (NumberOfDays <= 16))
EDIT: Maybe I misunderstood what you are asking (as pointed out in the comments). If you want a more generic solution for comparing dates, you can simply wrap your code into a function
bool AreDatesClose(DateTime d1, DateTime d2, double minDaysApart, double maxDaysApart)
{
var timespan = d1 - d2;
return timespan.TotalDays >= minDaysApart && timespan.TotalDays <= maxDaysApart;
}
You can write a function which will give you that NumberOfDays is in between given range or not
public bool IsGivenDateInRange(double numberOfDays, double startDate, double endDate)
{
return numberOfDays >= startDate && numberOfDays <= endDate;
}
Now use this function in if condition
if(IsGivenDateInRange(NumberOfDays, 14, 16)) //Instead of 14 and 16 you can use any number
{
//Your logic
}
As per new edit in your question if you want to show message box when date does not come in these range, then you can use same function but with negation
if(!IsGivenDateInRange(NumberOfDays, 14, 16)) //Instead of 14 and 16 you can use any number
{
//MessageBox.Show();
//Your logic
}
I am trying to optimize one of our most important queries and I would like to have some extra insights on how Entity Framework translates certain LINQ expressions.
I am using the repository pattern so my service layer (where I define my queries) is unaware of the actual data layer, which (currently) limits me to using only Where statements. Using joins and other constructs may help but that would require a rewrite of certain parts of the application. I'd like to exhaust all other options first before considering that.
I have come up with 3 variants of my query:
// Takes about 1900-2200ms for 120 records
public Expression<Func<Appointment, bool>> FilterByResources(DateTime startDate, DateTime endDate, IEnumerable<int> resourceIds)
{
// Appointments are filtered on the scheduler's start date, end date and the resources in the current page
Expression<Func<Appointment, bool>> filter = (x) => x.Assignments.Any(z => resourceIds.Contains(z.ResourceId))
&&
// Appointment starts somewhere between the start and end date
((DbFunctions.TruncateTime(x.StartDate).Value >= startDate && DbFunctions.TruncateTime(x.StartDate).Value <= endDate) ||
// Appointment started earlier than start date but ends earlier than end date
(DbFunctions.TruncateTime(x.EndDate).Value >= startDate && DbFunctions.TruncateTime(x.EndDate).Value <= endDate) ||
// Appointment starts and ends outside the boundaries
(DbFunctions.TruncateTime(x.StartDate).Value <= startDate && DbFunctions.TruncateTime(x.EndDate).Value >= endDate));
return filter;
}
Alternative #2:
// Takes about 2100ms for 120 records
public Expression<Func<Appointment, bool>> FilterByResources2(DateTime startDate, DateTime endDate, IEnumerable<int> resourceIds)
{
DateTime truncatedStartDate = startDate.Date;
DateTime truncatedEndDate = endDate.EndOfDay(); // Extension method that formats the time to 23:59:59
// Appointments are filtered on the scheduler's start date, end date and the resources in the current page
Expression<Func<Appointment, bool>> filter = (x) => x.Assignments.Any(z => resourceIds.Contains(z.ResourceId)) && (
(x.StartDate >= truncatedStartDate && x.StartDate <= truncatedEndDate) || // Appointment starts somewhere between the start and end date
(x.EndDate >= truncatedStartDate && x.EndDate <= truncatedEndDate) || // Appointment started earlier than start date but ends earlier than end date
(x.StartDate <= truncatedStartDate && x.EndDate >= truncatedEndDate) // Appointment starts and ends outside the boundaries
);
return filter;
}
Alternative 3:
// Takes about 1900ms for 120 records
public Expression<Func<Appointment, bool>> FilterByResources(DateTime startDate, DateTime endDate, IEnumerable<int> resourceIds)
{
DateTime truncatedStartDate = startDate.Date;
DateTime truncatedEndDate = endDate.EndOfDay(); // Extension method that formats the time to 23:59:59
// Appointments are filtered on the scheduler's start date, end date and the resources in the current page
Expression<Func<Appointment, bool>> filter = (x) => x.Assignments.Any(z => resourceIds.Contains(z.ResourceId)) && (
(x.StartDate.CompareTo(truncatedStartDate) >= 0 && x.StartDate.CompareTo(truncatedEndDate) <= 0) || // Appointment starts somewhere between the start and end date
(x.EndDate.CompareTo(truncatedStartDate) >= 0 && x.EndDate.CompareTo(truncatedEndDate) <= 0) || // Appointment started earlier than start date but ends earlier than end date
(x.StartDate.CompareTo(truncatedStartDate) <= 0 && x.EndDate.CompareTo(truncatedEndDate) >= 0) // Appointment starts and ends outside the boundaries
);
return filter;
}
A little explanation about this query: This query retrieves a list of appointments for a number of resources (i.e. people) between two dates. Because of that range, I need to include those records that start earlier, finish later or last longer than the range (hence the 3 expressions).
I tried switching the order of the expressions but the results remain stable. On average it takes between 1800ms and 2200ms for the entire web api call (I use postman for my tests)
So my question is how this query can be optimized? I think the date comparison expressions take the longest time but it may as well be the Any/Contains combination that slows down the query.
In my C# program I have run into an obstacle where I have a table that stores date ranges (columns are date range ID (int), begin date (DateTime) and end date (DateTime). I want to query the table and get back rows that only fall within a specific date range. I cannot use datetime.date since that includes the year.
So for example, I want to query the table and get all date ranges that fall between 01-01 and 5-31.
I have tried using the following lambda to query the table, but my result set is empty.
List<DateRanges> tempDateRangeList = dataContext
.DateRanges
.Where(r=>r.BeginDate.Month <= startDate.Month
&& r.EndDate.Month >= finishDate.Month)
.ToList();
tempDateRangeList = tempDateRangeList.Where(r=>r.BeginDate.Day <= startDate.Day
&& r.EndDate.Day >= finishDate.Day)
.ToList();
Does anyone have any suggestions on how I could accomplish this?
Edit:
Examples of BeginDate and EndDate would be a list such as follows:
BeginDate 1/1/2016, 5/25/2016, 9/11/2016
EndDates 5/24/2016, 9/10/2016, 12/31/2016
Filter date would be:
startDate = 12/8
finishDate = 12/12
Expected result:
Begin Date of 9/11
End date of 12/31
There are two cases in your condition - month equal to boundary month, in which case you must test day number, and a different month, in which you ignore day. Hence the query:
List<DateRanges> tempDateRangeList =
dataContext.DateRanges.Where(r =>
((r.BeginDate.Month < startDate.Month) ||
(r.BeginDate.Month == startDate.Month && r.BeginDate.Day <= startDate.Day)) &&
((r.EndDate.Month > finishDate.Month) ||
(r.EndDate.Month == finishDate.Month) && r.EndDate.Day >= finsihDate.Day))
.ToList();
Condition is ugly and very hard to follow but covers all cases. This query returns all records which define date ranges that completely fall under the boundary dates.
If you wish to find records that are just overlapping (completely or partially) with the filtering range, then the query would be:
List<DateRanges> tempDateRangeList =
dataContext.DateRanges.Where(r =>
((r.BeginDate.Month < endDate.Month) ||
(r.BeginDate.Month == endDate.Month && r.BeginDate.Day <= endDate.Day)) &&
((r.EndDate.Month > startDate.Month) ||
(r.EndDate.Month == startDate.Month) && r.EndDate.Day >= startDate.Day))
.ToList();
This condition may bend your mind, but it works fine.
If a lambda expression isn't compulsory, I've used linq queries (because it was the first solution i've thought).
var validRanges = from range in ranges
where range.BeginDate.CompareTo(startDate) <= 0
where range.EndDate.CompareTo(endDate) >= 0
select range;
Using CompareTo is the easiest way to compare two DateTime struct.
I invite you to take a look here for a complete description of the method.
Edit
If you aren't interested in hours of your dates, but only in Day and Month, you should use range.BeginDate.Date.CompareTo(startDate.Date) and range.EndDate.Date.CompareTo(endDate.Date)
trying to get all the dates from the db that are within the current week
i have email1DueDate, email2DueDate, email3DueDate
and i want to see if they are due to be sent within the current week
First you should calculate two DateTime values for the start of the week and the end of the week, you can do that like this (assuming Monday is the first day):
DateTime startOfWeek = DateTime.Today;
int delta = DayOfWeek.Monday - startOfWeek.DayOfWeek;
startOfWeek = startOfWeek.AddDays(delta);
DateTime endOfWeek = startOfWeek.AddDays(7);
next you can use this in your LINQ query to get the results you need, I am assuming you want results to be rows that have any of your due dates fall in the week:
var results = DB.Table.Where(x =>
(x.email1DueDate >= startOfWeek && x.email1DueDate < endOfWeek) ||
(x.email2DueDate >= startOfWeek && x.email2DueDate < endOfWeek) ||
(x.email3DueDate >= startOfWeek && x.email3DueDate < endOfWeek)
);
If this is not what you need then you will need to clarify your requirements
LINQ
listOfDates.Where(x => x.email1DueDate > beginOfWeekDate && x.email1DueDate < endOfWeekDate).ToList();
Of course you'll still have to figure out the begin and end dates
I'm faced with an issue where my application is doing a search for transactions based on a FROM and TO date.
Lets use the following example:
TRANS1: 14-Feb-2012 2:23:36
TRANS2: 07-Feb-2012 3:23:47
My date ranges in C# is as follow:
startDate.Date {7/02/2012 12:00:00 AM}
endDate.Date {14/02/2012 12:00:00 AM}
The following line of code will ALWAYS exclude transactions if they fall on the endDate because the endDate is always set to 12:00:00AM (Based on DateTime.Now)
if (trans.TransactionDate >= startDate.Date &&
trans.TransactionDate <= endDate.Date)
{
// do stuff
}
How do I correctly handle this so that it includes all transactions for the 14th as well? Is it safe to do the following:
Changing 12:00:00AM to 12:00:00PM
if (trans.TransactionDate >= startDate.Date &&
trans.TransactionDate <= endDate.Date.AddHours(12))
{
// do stuff
}
This may work:
if (trans.TransactionDate.Date >= startDate.Date && trans.TransactionDate.Date <= endDate.Date)
{
// do stuff
}