Entity Framework Core 6 - Date Comparision - asp.net-core

I need to create a query to find records between a date range. I need to truncate the time for comparison. I came across a few threads suggesting to truncate time using DbFunctions.TruncateTime when comparing the dates.
I cannot find DbFunctions class in EntityFrameworkCore 6.0. How do I truncate time and compare the DateTime columns?
Edit: Excerpt from my query handler
IQueryable<TestReportItem> query = _context.TestReportItems;
DateTime requestDateStart = DateTimeOffset.FromUnixTimeMilliseconds(request.TestDateStart).LocalDateTime;
DateTime requestDateEnd = DateTimeOffset.FromUnixTimeMilliseconds(request.TestDateEnd).LocalDateTime;
if (request.FacilityId != 0)
{
query = query.Where(e => e.FacilityId == request.FacilityId);
}
if (request.TestDateStart != 0 && request.TestDateEnd != 0)
{
query.Where(e => e.TestDate.Date >= requestDateStart
&& e.TestDate.Date <= requestDateEnd);
}
var count = query.Count();
return count;
The request will be for a date range (dates converted into UnixTimeMilliseconds). I am using SqLite database.

Related

Why does this Linq Query Return Different Results than SQL Equivalent?

I'm sure I'm missing something simple but I have a linq query here:
public static List<Guid> GetAudience()
{
var createdOn = new DateTime(2018, 6, 30, 0, 0, 0);
var x = new List<Guid>();
try
{
var query = from acc in Account
where acc.num != null
&& acc.StateCode.Equals(0)
&& acc.CreatedOn < createdOn
select new
{
acc.Id
};
foreach (var z in query)
{
if (z.Id != null)
{
x.Add(z.Id.Value);
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
return x;
}
I wanted to verify the count in SQL because it would only take a couple seconds so:
select count(*)
from Account a
where a.num is not null
and a.statecode = 0
and a.createdon < '2018-06-30 00:00:00'
And now the SQL query is returning 9,329 whereas Linq is returning 10,928. Why are my counts so far off when the queries are doing the same thing (so I thought)? What simple thing am I missing?
Thanks in advance--
Your method is returning a list of records where the Id values are not null (plus the other criteria). The SQL query is returning a count of the number of records (plus the other criteria). Without the definition of your table, it's hard to know whether that is significant.
Unrelated tip: it's not a good idea to catch and swallow exceptions like that - the caller of your method will have no idea that anything went wrong, so processing will continue; but it will be using incomplete data, potentially leading to other problems in your program later.

Search between Specific Times

I have a date field and 2 time fields(Start Time and End Time). I have to get Data from the date and entered in that date field and between Start and end times.
I am using Linq query.
result = result.Where(x => x.CreatedDate.ToLocalTime() > search.StartTime &&
x.CreatedDate.ToLocalTime() < search.EndTime);
I am using this but I am getting the following error.
LINQ to Entities does not recognize the method 'System.DateTime ToLocalTime()' method, and this method cannot be translated into a store expression
Please Help.
You can't use ToLocalTime() for Linq to Entities. Because it can't be translated to SQL. There is no equivalent to apply it.
So, why don't you convert your startTime and endTime by considering required time zone which is stored in the database. Opposite conversion should be like that;
//I use utc time to provide example.
//Convert your dates with required timezones which is stored in the database
var startTime = search.StartTime.ToUtcDateTime();
var endTime = search.EndTime.ToUtcDateTime();
result = result.Where(x => x.CreatedDate > startTime &&
x.CreatedDate < endTime);
As Panagiotis Kanavos pointed out there may be no equivalent argument. When you do have the correct type though you are essentially doing a conversion of one DateTime to another. Both the predicate values and the set should have their values preferably stored in the same TimeZone. Here is a simple console example to show what I mean.
public class TestData
{
public DateTime Dt { get; set; }
public TestData(DateTime dt)
{
Dt = dt;
}
public override string ToString() => Dt.ToString();
}
static void Main(string[] args)
{
var dt = new DateTime(2018, 1, 11);
var s = dt;
var e = dt.AddHours(3);
var dts = new List<TestData>();
for (int i = 0; i < 10; i++)
{
dts.Add(new TestData(dt.AddHours(i)));
}
Console.WriteLine("Dates as are");
dts.ForEach(Console.WriteLine);
Console.WriteLine(Environment.NewLine);
Console.WriteLine("Dates to local time are");
dts.ForEach(x => Console.WriteLine(x.Dt.ToLocalTime()));
Console.WriteLine(Environment.NewLine);
Console.WriteLine("searches are");
Console.WriteLine(s);
Console.WriteLine(e);
Console.WriteLine(Environment.NewLine);
Console.WriteLine("searches to local time are");
Console.WriteLine(s.ToLocalTime());
Console.WriteLine(e.ToLocalTime());
Console.WriteLine(Environment.NewLine);
Console.WriteLine("Weird results as one set is cast to local and other is not. Plus the cast is now performed on presentation");
dts.Where(x => x.Dt.ToLocalTime() >= s && x.Dt.ToLocalTime() <= e).ToList().ForEach(Console.WriteLine);
Console.WriteLine(Environment.NewLine);
Console.WriteLine("expected results as both are uniform");
dts.Where(x => x.Dt >= s && x.Dt <= e).ToList().ForEach(Console.WriteLine);
Console.ReadLine();
}
Since different posters on SO are in different timezone the second result set will vary. But essentially I am in PST in the US so I see times for the second set eight hours prior to my first. You generally in .NET perform operations of storage to be UTC if your application is going to be worldwide or even country wide. Then you just deal with DateTimes and would only do a conversion on the client end for presentation to a potential end user. But most of the time not in the logic for predicates.

date time condition in razor view

How to set a condition to say if a data in a table is less than 5 days ago and then display a users information.
Below I can say less than date now.
#foreach (var item in Model)
{
if(item.RegisteredAt < DateTime.Now )
{
}
}
You can get the difference between two dates as a TimeSpan and use TotalDays property.
(DateTime.Now - item.RegisteredAt).TotalDays < 5
You can pass in a negative number to the AddDays function.
if(item.RegisteredAt < DateTime.Now.AddDays(-5)) {
If you wanted to ignore the time portion then you should compare them off the Date property.
if(item.RegisteredAt.Date < DateTime.Today.AddDays(-5)) {
if(item.RegisteredAt.Substract(DateTime.Now).Days.ToString().AsInt() < 5)
{
#* your expected code *#
}

Difference between datepickers except sundays in infopath

How to get the no of days between two date picker controls in info path except sundays?
If It is possible let me know.
Thanks in advance.........
Using custom code you can do it easily. In this case I'm calculating the number of days (except Sundays) between a given date and today's date.
var navigator = this.MainDataSource.CreateNavigator();
string startDate = navigator.SelectSingleNode("/my:myFields/my:date_start", NamespaceManager).Value;
DateTime startDateTime = DateTime.ParseExact(startDate, "yyyy-MM-dd", null);
DateTime today = DateTime.Today;
int count = 0;
while (startDateTime > today)
{
today = today.AddDays(1);
if (today.DayOfWeek != DayOfWeek.Sunday)
{
count++;
}
}
I hope it helps

Convert SQL - LINQ - Problem with using both Min/Max

Is there a online system which converts SQL - LINQ or can anyone else help convert the SQL - LINQ below?
SELECT MIN(startTime) As startTime, MAX(endTime) As endTime
FROM tblRA
LEFT JOIN tblA ON tblRA.asID = tblA.asID
WHERE 'xxxxxx' BETWEEN tblRA.startDate AND tblRA.endDate
AND tblA.availabilityDayOfWeek = 7
The main area I am having trouble is the .MAX/.MIN.
Heres what I have so far
public List<string> GetResourceAvailabilitiesByDate(DateTime searchDate)
{
DayOfWeek dayOfWeek = searchDate.DayOfWeek;
var minVal = from a in dc.tblResourceAvailabilities
join b in dc.tblAvailabilities on a.asID equals b.asID
where searchDate.Date >= a.startDate.Date && searchDate.Date <= a.endDate.Value.Date
&& b.availabilityDayOfWeek == (int)dayOfWeek
select b.startTime.ToShortTimeString();;
var maxVal = from a in dc.tblResourceAvailabilities
join b in dc.tblAvailabilities on a.asID equals b.asID
where searchDate.Date >= a.startDate.Date && searchDate.Date <= a.endDate.Value.Date
&& b.availabilityDayOfWeek == (int)dayOfWeek
select b.endTime.ToShortTimeString();
var min = minVal.Min(minVal.Min);
var max = maxVal.Max();
return min,max;
Thanks in advance for any help
Clare
I think your code is a little bit incorrect, and the first symptom of it is that you are using repeated code to define minval and maxval. I tried to simulate something similar to what you want and came to the following code, please adapt it to your needs.
public List<string> GetResourceAvailabilitiesByDate(DateTime searchDate)
{
DayOfWeek dayOfWeek = searchDate.DayOfWeek;
var vals = from a in dc.tblResourceAvailabilities
join b in dc.tblAvailabilities on a.asID equals b.asID
where searchDate.Date >= a.startDate.Date && searchDate.Date <= a.endDate.Value.Date
&& b.availabilityDayOfWeek == (int)dayOfWeek
select b;
var min = vals.Min(v => v.startTime).ToShortTimeString();
var max = vals.Max(v => v.startTime).ToShortTimeString();
return new List<string>() { min, max };
}
Some comments on your code, assuming it's C#.
You are trying to return an array of strings when you should be returning an array of dates.
Your where clause is pretty confuse. You're comparing the search date with startdate.Date and endDate.Value.Date. It does not make much sense.
Your select clause could select only b, or a, or whatever. You don't really need to select the date in it.