OData Query with DateTimeOffset - linq

Using LINQPad to query a OData v2 server to find records that have recently been modified and getting unexpected results:
// Define a DateTimeOffset to test against
DateTimeOffset testDateTimeUTC = DateTimeOffset.UtcNow.AddMinutes(-180);
// Detect changes that have occurred since the test DateTimeOffset
var changedRecords = EmpJob
.Where (e => e.lastModifiedDateTime >= testDateTimeUTC);
changedRecords.Dump();
Generates the query string:
https://api10.successfactors.com/odata/v2/EmpJob()?$filter=lastModifiedDateTime ge datetimeoffset'2017-05-05T00:12:18.9383091Z'
I get three results back, one is correct and the other two are time-stamped as:
3/10/2016 1:01 AM +00:00 and 21/12/2016 1:37 AM +00:00 which are clearly invalid.
To me it looks like a server side issue, can anyone see a problem that I'm missing?

Using a filter with a start and an end date resolved the issue.

Related

Count maching date data [duplicate]

I need to call ToShortDateString in a linq query suing lambda expressions:
toRet.Notification = Repositories
.portalDb.portal_notifications.OrderByDescending(p => p.id)
.FirstOrDefault(p => p.date.ToShortDateString() == shortDateString);
but I get the error:
An exception of type 'System.NotSupportedException' occurred in
System.Data.Entity.dll but was not handled in user code
Additional information: LINQ to Entities does not recognize the method
'System.String ToShortDateString()' method, and this method cannot be
translated into a store expression.
What can I do, considering that I do need to use ToShortDateString() ?
Thanks.
Linq to Entities cannot convert ToSortDateString method into SQL code. You can't call it on server side. Either move filtering to client side (that will transfer all data from server to client), or consider to use server-side functions to take date part of date (you should pass DateTime object instead of shortDateString):
EntityFunctions.TruncateTime(p.date) == dateWithoutTime
You shouldn't be forcing a string comparison when what you're working with is Date/time data - as soon as you force string comparisons, you're suddenly having to deal with how the strings are formatted.
Instead, have something like:
var endDate = targetDate.AddDays(1);
toRet.Notification = Repositories
.portalDb.portal_notifications.OrderByDescending(p => p.id)
.FirstOrDefault(p => p.date >= targetDate && p.date < endDate);
(Assuming that targetDate is whatever DateTime variable you had that was used to produce shortDateString in your code, and is already a DateTime with no time value)
Try this,
You can also used with below code.
Activity = String.Format("{0} {1}", String.Format("{0:dd-MMM-yyyy}", s.SLIDESHEETDATE), String.Format("{0:HH:mm}", s.ENDDATETIME))
ToShortDateString() method usually used to work only with date and ignore time stamps.
You will get exactly today result-set by using the following query.
Repositories.portalDb.portal_notifications.OrderByDescending(p => p.id)
.FirstOrDefault(p => p.date.Date == DateTime.Now.Date);
By using Date property of DateTime struct you can just fetch record of that date only.
Note: Linq to Objects. Only works if you CAN (or have option) to bypass ToShortDateString() method

Windows Phone LocalDB Method has no supported translation to SQL

I want compare datetime (i need parse it) with now in LINQ query
From i In db.Downloads
Where i.WantExpiration And DateTime.Parse(i.Expiration) < DateTime.Now
Everytime i get error: Method 'System.DateTime Parse(System.String)' has no supported translation to SQL.
How i can in LINQ to SQL parse datetime?
You could do this:
From i In db.Downloads
Where i.WantExpiration And i.Expiration < DateTime.Now
provided that Expiration is a DateTime column in your DB.
The error you are getting is expected since LINQ-SQL translates our linq queries in sql and then send them in the db, where there are executed and the results travel back to us. That being said, there isn't something similar like DateTime.Parse() in sql, so this method cannot be converted to a corresponding one in SQL. Hence your query cannot be translated in SQL.
If Expiration isn't a DateTime column in your DB, then you could make the following trick
(I see that you query is written in VB, but since I don't use VB, I will write my own in C# and subsequently, you could change it to VB.)
// Initially you will get all your data in memory.
var query = (from d in db.Downloads
select d).AsEnumerable();
// Then you will query the in memory data.
var data = (from q in query
where q.WantExpiration &&
DateTime.Parse(q.Expiration) < DateTime.Now);

LINQ 2 Entities-query is not working, but why?

everyone! ))
Here is code.
var existingEntities = (from record in globalOne.serviceContext.records_out
where record.timestamp.Date == DateTime.Now.Date
select record ).ToList();
It doesn't work.
Another code:
var existingEntities = (from record in globalOne.serviceContext.records_out
where record.timestamp.Day == DateTime.Now.Day
select record ).ToList();
It does work.
So, problem id in next string:
where record.timestamp.**Date** == DateTime.Now.Date
also won't do
where record.timestamp.Date.Equals(DateTime.Now.Date)
But why? I have no clue. "Timestamp" field is dateTime field in MS SQL SERVER.
And - there is NO records in table.
And I almost forgot - what does it mean - "doesn't work".
App just will not reach the breakpoint after that query(first), without any error, without anything.
Thanks.
You can call record.timestamp.Date because EF can't convert it to required expression tree (then convert it to sql command). In fact EF supports limited number of functions and properties, But for DateTime, EF has some good Canonical functions. You can use them in your case, e.g you can use Day(),Month(),Year() functions to solve your problem (see the link).

Linq Containsfunction problem

I use Ria Service domainservice for data query.
In My database, there is a table People with firstname, lastname. Then I use EF/RIA services for data processing.
Then I create a Filter ViewModel to capture user inputs, based it the input, I construct a linq Query to access data.
At server side, the default DomainService query for person is:
public IQueryable<Person> GetPerson()
{
return this.Context.Person;
}
At client side, the linq Query for filter is something like(I use Contains function here):
if (!String.IsNullOrEmpty(this.LastName))
q = q.Where(p => (p.LastName.Contains(this.LastName)));
The generated linq query is something like(when debugging,I got it):
MyData.Person[].Where(p => (p.LastName.Contains(value(MyViewModel.PersonFilterVM).LastName) || p.Person.LegalLastName.Contains(value(MyViewModel.PersonFilterVM).LastName)))
When I run the app, I put "Smith" for last name for search, but the result is totally irrelevant with "Smith"!
How to fix it?
I'm guessing here as to what your error is so this might not work for you.
In your 2nd code snippet you do the following.
q = q.Where(p => (p.LastName.Contains(this.LastName)));
This is where I think your error is. Linq does not evaluate the where clause until you iterate over it. Try changing the line to the following.
qWithData = q.Where(p => (p.LastName.Contains(this.LastName))).ToList();
The .ToList() call will load the query with data.
When you check in the debugger, does value(MyViewModel.PersonFilterVM).LastName evaluate to Smith at the time the query is resolved?
Recall that queries are not resolved until they are enumerated.

LINQ - Distinct() returning a different value if extension method used

I have a LINQ query which is attempting to get all of the distinct months of all of the dates in a table.
I had this working using the Distinct() extension method. I then made it more readable by using an extension method to extract the month. And then it stopped returning Distinct results.
Can anyone help me work out what happened here?
As an aside, if someone can tell me the best way to get the distinct months, that would be nice too. But it's more important that I understand why this is failing.
Here's the code.
static class DcUtils
{
public static DateTime GetMonth(this Timesheet_Entry entry)
{
DateTime dt = new DateTime(
entry.Entry_Start_DateTime.Year,
entry.Entry_Start_DateTime.Month,
1
);
return dt;
}
}
public class Demo
{
public DemonstrateBug()
{
TimesheetDataClassesDataContext dc = new TimesheetDataClassesDataContext();
/////////////////////////////////
//// Here are the queries and their behaviours
var q1 = (
from ts
in dc.Timesheet_Entries
select new DateTime(ts.Entry_Start_DateTime.Year, ts.Entry_Start_DateTime.Month, 1)
).Distinct();
// This returns 3 (which is what I want)
int lengthQuery1 = q1.Count();
// And now for the bug!
var q2 = (
from ts
in dc.Timesheet_Entries
select ts.GetMonth()
).Distinct();
// This returns 236 (WTF?)
int lengthQuery2 = q2.Count();
}
}
LINQ to SQL is smart enough to convert the new DateTime() expression from your initial lambda expression into a SQL statements that can be executed at the server. If you replace this expression with an (extension) method, LINQ to SQL will only see a call to an opaque method it knows nothing about, hence it cannot generate any SQL for the method call and the part of the SQL query messing with the dates disappears.
But this shouldn't break anything - what cannot be transformed into SQL must be executed at the client. So what happens? The date you want to perform the distinct operation on cannot be calculated at the server because of the opaque method call, hence the distinct operation cannot be performed at the server, too. But the query you recorded from the broken version contains a DISTINCT statement.
I don't use the LINQ query syntax, but I assume you have written something you don't actually mean or the compiler or LINQ to SQL inferred something you didn't mean.
context
.Timesheet_Entries
.Select(tse => tse.GetMonth())
.Distinct()
versus
context
.Timesheet_Entries
.Distinct()
.Select(tse => tse.GetMonth())
So I guess you got the second one for what ever reason - the distinct operation seems to get propagated over the select. Maybe it's the combination of Distinct() with the query syntax and the contained opaque method call. Try both versions without the query syntax and see what you get back and what queries are send to the server. You can also try to insert ToList() calls to force the transition from LINQ to SQL to LINQ to Objects - this might help to cast some light onto the situation, too.
It occurred to me to run this through the SQL Server Profiler.
This query:
var q1 = (
from ts
in dc.Timesheet_Entries
select new DateTime(ts.Entry_Start_DateTime.Year,
ts.Entry_Start_DateTime.Month,
1)
).Distinct();
generates the following SQL. As you can see, it converted the System.DateTime calls into Transact SQL.
SELECT DISTINCT
[t1].[value]
FROM (
SELECT
CONVERT(
DATETIME,
CONVERT(
NCHAR(2),
DATEPART(
Month,
[t0].[Entry_Start_DateTime]
)
)
+ (''/'' + (CONVERT(NCHAR(2), #p0)
+ (''/'' + CONVERT(NCHAR(4),
DATEPART(
Year,
[t0].[Entry_Start_DateTime]
)
)
))), 101
) AS [value]
FROM [dbo].[Timesheet_Entry] AS [t0]
) AS [t1]
But if I put the month extraction logic in the extension method:
var q2 = (
from ts
in dc.Timesheet_Entries
select ts.GetMonth()
).Distinct();
It generats the following SQL.
SELECT DISTINCT
[t0].[Timesheet_Entry_ID],
[t0].[Entry_Start_DateTime],
[t0].[Entry_End_DateTime],
[t0].[Task_Description],
[t0].[Customer_ID]
FROM [dbo].[Timesheet_Entry] AS [t0]
So it's moved the DISTINCT function to the server, but kept the date extraction code until after the DISTINCT operation, which is not what I want, and is not what happens in the first example.
I don't know if I should call this a bug or a leaky abstraction.

Resources