I have started using Linq to SQL for a project im working on and i have run into a problem when ordering by a DateTime field but since the DateTime allows nulls the nulls are coming up as less than the actual dates in there.
So i pretty much want the ones with a date to be at the top (ordered either way) then all the ones with no date set.
jobList = from ju in context.Job_Users_Assigned
where ju.UserID == user.ID
select ju.Job;
return jobList.OrderByDescending(j => j.EndDate);
This is a bit of a hack, but it appears to work with Linq to SQL:
return from ju in context.Job_Users_Assigned
where ju.UserID == user.ID
orderby ju.Created ?? DateTime.MaxValue descending;
So I'm substituting the maximum possible DateTime value when the actual "Create" value is null. That'll put all the null values at the top.
Another approach is to order by whether the date field has a value. This works too:
return from ju in context.Job_Users_Assigned
where ju.UserID == user.ID
orderby ju.Created.HasValue descending
orderby ju.Created descending;
Related
I am trying to return records for users based on their telephone numbers as well as a restriction to the PolicyEnd Field (DateTime Format) to return only those that are greater than or equal to 2022. However, I keep on running into several errors:
&& DateTime.ParseExact(s: ti0.Outer.Inner.PolicyEnd,format: "yyy-MM-dd",provider: __InvariantCulture_0) > DateTime.Now)' could not be translated.
var QUERY = from client in _ipacontext.Inclients
join policy in _ipacontext.Inpolicies on client.ClientId equals policy.AccountNo
join types in _ipacontext.InpolicyTypes on policy.PolicyType equals types.TypeId
where client.Telephone2 == "0000000" && DateTime.ParseExact(policy.PolicyEnd, "yyy-MM-dd", CultureInfo.InvariantCulture) > 2022
I have also tried this below but in vain :
where client.Telephone2 == "000000" && Convert.ToDateTime(policy.PolicyEnd).Year >=2022
An example of the Date Format is as below:
2022-08-31 00:00:00.000
Any help on other workarounds?
Dates have no format, they're binary types in all databases (except SQLite). SQL Server has date, datetime2, datetimeoffset, time and the legacy datetime for storing dates and time-of-day. Storing dates as strings in a string field is a critical bug that must be fixed. There's no way to control what goes into a string field, which means it's quite easy for garbage or strings with the wrong format to end up in the database.
Trying to parse such strings will result in bad performance and increased blocking even if indexes are used. Indexes are built using the stored values, not function results. Trying to parse PolicyEnd and filter by a specific date would have to scan the entire table, parse the values and only then decide which values to include. It will take Shared locks on the entire table while doing so, which would block any UPDATE or DELETE calls that tried to run at the same time, even if they were outside the date range.
If the field uses a date type, the PolicyEnd property should be a DateTime. In that casefiltering to find all dates after 2022 would be just :
var fromDate=new DateTime(2023,1,1);
var query = ....
where client.Telephone2 == "000000"
&& policy.PolicyEnd >=fromDate
This will result in a parameterized query that can use any indexes covering PolicyEnd to only touch policy rows whose PolicyEnd value matches the criteria.
The JOINs aren't necessary either. It's EF's job to generate the JOINs from the relations between entities. A Client should have a Policies collection. A Policy should have a PolicyType. A LINQ query that returns clients without a second phone whose policies end in the future should be :
var clients=from client in _context.Clients
from policy in client.Policies
where client.Telephone2 == "000000"
&& policy.PolicyEnd >=fromDate
select ...;
Since your db table column format datetime, just try to use function
var dt = new DateTime(2022,01,01);
....
&& EF.Functions.DateDiffYear(policy.PolicyEnd, dt) >= 0
or since you are checking only year you can try to use the whole data, sometimes it works
var dt = new DateTime(2021, 12, 31).AddDays(1).AddTicks(-1);
...
&& policy.PolicyEnd > dt
I'm trying to run a query of a table with the columns Domain, LastUsed, and FreqInHours In c#.
I just want to return all the Domains that I need to crawl.I find this out by checking the datetime that they were last Crawled (LastUsed) and how frequently they should be crawled (ex. every 6 hours). If the current date/time - the time it was last crawled is greater than the frequency I add want to return that domain.
Here is the current query I've written:
var query = (from c in context.SitemapFreqs
where (DateTime.Now - c.LastUsed).TotalHours > c.Freq
select c.domain);
Here is the exception I'm being given:
LINQ to Entities does not recognize the method 'System.DateTime ?
ToDateTime(System.Object)' method, and this method cannot be translated into a store expression.
Any help would be really appreciated.
You can use DbFunctions class and method DiffHours.
Here is an example:
var query = (from c in context.SitemapFreqs
where DbFunctions.DiffHours(DateTime.Now,c.LastUsed) > c.Freq
select c.domain);
Here is the documentation. Hope it helps.
Complex DateTime stuff is a bit much for Linq2SQL to handle.
If it's a relatively small amount of data, load it all into memory first:
var query = (from c in context.SitemapFreqs.ToList()
where (DateTime.Now - c.LastUsed).TotalHours > c.Freq
select c.domain);
If it's a larger amount of data, you can use DbFunctions, or provide the query yourself.
context.SitemapFreqs.SqlQuery("SELECT * from SitemapFreqs WHERE DATEDIFF('hour', GETDATE(), LastUsed) > Freq")
If you make sure the query returns the columns the SitemapFreqs object expects, it will map the objects just like it would anything else.
Looks like your c.LastUsed property is nullable. You can subtract nullable DateTimes using the c.LastUsed.Value property, but you should know that if it is null, this will throw an exception as you can't subtract a DateTime - null. I believe you have two options:
Change the property LastUsed in your class to a non-nullable DateTime by removing the ?.
Create a method inside of your class that determines if the DateTime? LastUsed is equal to null. If it is, return something where your LINQ query will ignore that value. (I.E: Set the value of LastUsed = DateTime.Now so that your LINQ query comes back as 0).
Hope this helps.
I have a simple LINQ query. I would like to only check the DateDisable if there is an entry in the database. If the user doesn't select a date to disable the entry will always show. Can someone please show me how to add a conditional statement within linq
return (from promo in context.Promoes
where promo.DateEnable <= DateTime.Today
where promo.DateDisable >= DateTime.Today
orderby promo.SortOrder
select promo).ToList();
Given that DateEnable is a DateTime?, you can do the following:
// Get today.
DateTime today = DateTime.Today;
return (
from promo in context.Promoes
where
promo.DateEnable <= today &&
(promo.DateDisable == null || promo.DateDisable >= today)
orderby promo.SortOrder
select promo
).ToList();
Basically, you need to check for null or whether or not the date is greater than today.
Also you should capture the value outside of the statement, it's not guaranteed that the the LINQ provider will translate DateTime.Today on the database side correctly.
However, be warned that because of deferred execution, if you wait a long time to execute the query, today might not give you the value you expect (if the time between declaring the query and executing it rolls past midnight).
Of course, if your database server is in a different timezone than your application server, then you'll need to ensure that DateTime.Today is handled by your LINQ provider correctly (so that it's executed on the server) and use that if you want to compare against time on the DB server. If your provider doesn't handle translating DateTime.Today correctly, then you'll have to resort to a stored procedure and call that.
I need to select the most recent date from my database table and store it in a variable.
I'm not very familiar with linq to entities but I gave it a go myself however I only got so far.
This is how far I got:
IQueryable<DateTime> date = from ftp in ctn.FTPRuns
orderby ftp.LastRun descending
select ftp.LastRun;
Can anyone tell me how I can modify this query to just select the most recent entry. I have tried "select ftp.LastRun.First();" however this is not an option in intellisense for me.
any help would be appreciated.
thanks.
The result of what you have there (date) is an ordered IQueryable. You can just call date.First() to get the first one in that sequence.
Otherwise if you want to cut a step, wrap your query in brackets and call.First on it to just get the date.
DateTime date = (from ftp in ctn.FTPRuns
orderby ftp.LastRun descending
select ftp.LastRun).First();
You could otherwise use lambdas:
DateTime date = ctn.FTPRuns.OrderByDescending(f => f.LastRun).First().LastRun;
IQueryable<DateTime> dates = from ftp in ctn.FTPRuns
orderby ftp.LastRun descending
select ftp.LastRun;
DateTime date = dates.First();
var islemList = (from isl in entities.Islemler where (isl.KayitTarihi.Date >= dbas && isl.KayitTarihi.Value.Date <= dbit) select isl);
It gives error: date is not supported in LINQ to Entities...
How can i get date in linq.
Use EntityFunctions.TruncateTime.
if KayitTarihi is a date column in DB (and dbas and dbit are DateTime), use:
var islemList = (from isl in entities.Islemler where (isl.KayitTarihi >= dbas && isl.KayitTarihi <= dbit) select isl);
The .Date property is not supported in Linq to Entities (though it may be supported in other implementations of Linq).
I realize that you only want to compare the dates, but there is no real problem with comparing the datetimes if the dbas and dbit values are datetimes with time 00:00:00.
You might have to offset the dates or use other inequality checks to get the proper interval but the comparison will work as you intend.
I would personally go with Jandek's solution.