(I am using LINQ to SQL for retrieving the table from database)
I need to loop through a Database table(the has a field Data) to mach the current date with the date in table.How can i achieve this?
Don't use a loop - this will be extremely slow if the table is large. You want to do this in a set based fashion - the IQueryable .Where() method, i.e:
MyTable.Where(x => x.SomeDate == DateTime.Today);
This assumes the dates in the DB store the date part only. If the time part is stored in the DB and you want to ignore that in the comparison, you need to do something like:
MyTable.Where(x => x.SomeDate >= DateTime.Today && x.SomeDate < DateTime.Today.AddDays(1));
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
When I want to do some validation stuff on database entities, I can think of two ways:
1: Retrive the field value and then do the calculations in the application:
if (dbContext.Coupons.Where(c=> c.Id == couponId).Select(c=> c.ExpirationDate).Single() <= DateTime.Now)
2: Do the calculations in the query (in 'Select()' method) and then retrive the result:
if (dbContext.Coupons.Where(c=> c.Id == couponId).Select(c=> c.ExpirationDate <= DateTime.Now).Single())
I suggest, every validation, filter or process do within linq or process that take value from db (SQL Query) or object.
for example :
if you have 10 datas in table and you use the second way, the app will import all data into local memory and filtered inside app.
but if you use the first way, the app only import the datas that already filtered (example only 4 datas after filter process)
if your datas is more than 10K maybe you'll see the different
This will give you best performance.
if (dbContext.Coupons.Any(c => c.Id == couponId && c.ExpirationDate <= DateTime.Now))
I am trying to pull data from a database by begin/end date parameters.
However the date that I need to filter on is stored as a string in Oracle DB.
Using linq how can I filter the dates out based on my parameters (which will be in a DateTime type)?
I originally tried:
var test = context.MY_TABLE
.Include(x => x.MY_DETAILS)
.Where(x => startDate >= MyHelpers.ConvertDate(x.DATE_FIELD) &&
endDate <= MyHelpers.ConvertDate(x.DATE_FIELD))
.ToList();
I understand the error because linq can't generate the necessary sql statements from my method.
So how can I compare the dates with linq that are stored in the DB as a string?
To boot I won't know how the date will be stored in the string. For the time being I will assume '3/10/2016 12:30:00' will be the date string.
How big is the list? On .NET side the easiest way would be parsing the string into DateTime method and compare the results. But it is not possible to do that on Database side because EF cannot translate methods like DateTime.Parse or your MyHelpers.ConvertDate.
If your list is not very large (you must decide what "large" exactly means) you can "download all into .NET" and handle the data there. This can be done by calling ToList or ToArray before the first custom method is called.
var test = context.MY_TABLE
.Include(x => x.MY_DETAILS)
.ToList() // or .ToArray()
.Where(x => startDate >= MyHelpers.ConvertDate(x.DATE_FIELD) &&
endDate <= MyHelpers.ConvertDate(x.DATE_FIELD))
.ToList();
But this solution can be slow if you have a large result set and if you don't need the complete data it is pretty wasteful.
Another way I see is, not accessing the DbSet<T> but using a stored procedure. This procedure can parse the strings, compare them and return only what you really need.
SPs can be easily accessed in EF like the table data but the select-code is on database side written in SQL.
As mentioned by RIanGillis you can use ExecuteSqlCommand instead of a stored procedure too. This method takes an SQL string as an argument, so you can use any conversion method that is available in your database. It works similar to a stored procedure but the SQL statement would be stored in the .NET code.
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.
I'm not sure if it's possible but I've been trying for half a day to use only date for filtering records in MS SQL database and I get to this question. I'm using Repository pattern so I get all records for my entity like this :
var rows = DocumentsRepository.All();
The table Documents has column Date of type datetime, I need to keep the time in the database but when I prepare it for filtering I want to use only the date and if possible to set the hours, minutes, seconds and millisecs to zeroes.
Is it possible and how to do it inside a LINQ?
I would guess EntityFunctions.TruncateTime(datetimeObj) does the trick if you are using EF in your repository.
IQueryable<Entity> query = query.Where(x => EntityFunctions.TruncateTime(x.CreatedAt) == DateTime.Today);
var someList = query.ToList();