Linq to Entity get a Date from DateTime - c#

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.

Related

Using Where clause for DateTime field using a LINQ statement

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

LINQ to entities compare DateTimeOffset's only date part

I am trying to compare only date part of DateTimeOffset in Linq. But auto generated query still add timezone. I am using DbFuncation.TruncateTime but it is only truncate time part. Timezone part is still comparing. May I know how can I compare DateTimeOffset's DateTime part only.
query.Where(p =>
DbFunctions.TruncateTime(p.ETD) >= trimCriteriaDto.StartDate
&& DbFunctions.TruncateTime(p.ETD) <= trimCriteriaDto.EndDate);

DevForce 2010 Formatting Dates for EntityQuery

I've run into a situation where I need to query by Date and Time. I'm trying to write an EntityQuery where the date and time are in the same format. The query below returns no rows. However if I remove the two date clauses, rows are returned and then I can check the dates looping through the results. I would prefer to use the dates in the query.
the variable ap in the query is a C# object
var query = from log in Manager.Logs
where log.StartDttm == ap.StartDttm
&& log.EndDttm == ap.EndDttm
&& log.TypeId == 1
select log;
I came up with this workaround to query between midnight and 11:59:59pm for each date. I don't like this either, but this does at least reduce the number of rows returned by the query.
var query = from log in Manager.Logs
where && log.StartDttm >= ap.StartDttmQueryBegin
&& log.StartDttm <= ap.StartDttmQueryEnd
&& log.EndDttm >= ap.EndDttmQueryBegin
&& log.EndDttm <= ap.EndDttmQueryEnd
&& log.TypeId == 1
select log;
DevForce doesn't expect any specific date/time formats or modify them when the query is built and executed, but it's not the date format per se but the precision of the data stored in the database vs. the precision of the DateTime fields in the "ap" object which is causing the issue.
In EF you can use the EntityFunctions and/or SQLFunctions APIs to perform date/time truncating/formatting, but these are difficult to use in DevForce due to the client/server serialization and EntityQuery to ObjectQuery conversion that DevForce performs. These APIs can be made to work on the "server side" of DevForce via an RPC call.
Your workaround, although it may feel cumbersome, is probably your best option. You could also try calling a stored procedure or using an ESQL passthru query, both of which will give you a little more control over the resulting SQL query.

How do I perform date-part comparison in EF

i heard people saying date time comparison do not work just due to time part because datetime has time part.
in sql i always compare datetime like this way and it works fine
select * from employee
where convert(varchar,dob,112) > '20111201' // this yyyymmdd format.
how could i simulate this in a LINQ query?
If you're using .NET 4 or above, just use the EntityFunctions.TruncateTime helper method. This will translate this type of datetime-to-date conversion to SQL for you.
from e in EfEmployeeContext
where EntityFunctions.TruncateTime(e.DOB) > new DateTime(2011,12,01);
The one thing to keep in mind is that operations on DateTime structs that represent database columns don't translate to SQL. So, you cannot write a query like:
from e in EfEmployeeContext
where e.DOB.Date > new DateTime(2011,12,01);
... because e.DOB represents the DOB column in the database, and EF won't know how to translate the Date sub-property.
However, there's an easy workaround depending on what dates you want:
If you want to include all employees that have a DOB on 12/01/2011 as well as those born after that date, then simply query:
from e in EfEmployeeContext
where e.DOB > new DateTime(2011,12,01);
If you want to include only employees born after 12/01/2011, then query:
from e in EfEmployeeContext
where e.DOB >= new DateTime(2011,12,02);
In short, the criteria, meaning a constant or literal DateTime you're comparing against, can be set up however you want. You just can't make radical modifications to properties that represent DB columns within the where predicate. That means you can't compare one DateTime column to a projection of another DateTime column, for instance:
//get all employees that were hired in the first six months of the year
from e in EfEmployeeContext
where e.HireDate < new DateTime(e.HireDate.Year, 7, 1);

Compare date if there is a date in the database

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.

Categories