tags:

views:

72

answers:

3

I am thoroughly frustrated right now. I am having an issue with LINQ-To-SQL. About 80% of the time, it works great and I love it. The other 20% of the time, the query that L2S creates returns the correct data, but when actually running it from code, it doesn't return anything. I am about to pull my hair out. I am hoping somebody can see a problem or has heard of this before. Google searching isn't returning much of anything.

Here is the linq query...

var query = from e in DataLayerGlobals.GetInstance().db.MILLERTIMECARDs
        where e.deleted_by == -1
        && e.LNAME == lastName
        && e.FNAME == firstName
        && e.TIMECARDDATE == startDate.ToString("MM/dd/yyyy")
        group e by e.LNAME into g
        select new EmployeeHours
        {
            ContractHours = g.Sum(e => e.HRSCONTRACT),
            MillerHours = g.Sum(e => e.HRSSHOWRAIN + e.HRSOTHER),
            TravelHours = g.Sum(e => e.HRSTRAVEL)
        };

This is the generated query....

 SELECT SUM([t0].[HRSCONTRACT]) AS [ContractHours], 
        SUM([t0].[HRSSHOWRAIN] + [t0].[HRSOTHER]) AS [MillerHours], 
        SUM([t0].[HRSTRAVEL]) AS [TravelHours]
 FROM [dbo].[MILLERTIMECARD] AS [t0]
 WHERE ([t0].[deleted_by] = @p0) 
    AND ([t0].[LNAME] = @p1) 
    AND ([t0].[FNAME] = @p2) 
    AND ([t0].[TIMECARDDATE] = @p3)
 GROUP BY [t0].[LNAME]

Now when I plug in the EXACT same values that the linq query is using into the generated query, I get the correct data. When I let the code run, I get nothing.

Any ideas?

+1  A: 

My instinct is telling me that you need to be pulling out DataLayerGlobals.GetInstance().db.MILLERTIMECARDs into an IQueryable variable and executing your Linq query against that, although there really should be no difference at all (other than maybe better readability).

You can check the results of the IQueryable variable first, before running the Linq query against it.

To extend this concept a bit further, you can create a series of IQueryable variables that each store the results of a Linq query using each individual condition in the original query. In this way, you should be able to isolate the condition that is failing.

Robert Harvey
+1  A: 

What type is TIMECARDDATE? Date, datetime, datetime2, smalldatetime, datetimeoffset or character?

Any chance local date/time settings are messing up the date comparison of startDate.ToString(...)? Since you're sending @p3 as a string, 01/02/2009 may mean Feb 1st or January 2nd, depending on the date/time setting on the server.

Remus Rusanu
TIMECARDDATE is a string. Yes, yes, I know. I inherited this database, and changing it is not an option. This maybe the issue. It works when the date is 10/19/2009, but doesn't work when the date is 10/5/2009. Would this be a SQL Server issue or LINQ issue?
Eclipsed4utoo
@Eclipsed4utoo Your comment about the failure on 10/5/2009 and the fact that the db dates are just strings makes me think your format string should be "MM/d/yyyy" instead so that you get "10/5/2009" and not "10/05/2009" as your current code would.
imaginaryboy
Dude...you are so awesome. That was it. I ended up using "M/d/yyyy" so the months wouldn't have a leading 0 which seemed to also cause the issue.
Eclipsed4utoo
+1  A: 

I'd also have a look at the LNAME & FNAME data types. If they're NCHAR/NVARCHAR you may need to Trim the records, e.g.

var query = from e in DataLayerGlobals.GetInstance().db.MILLERTIMECARDs
    where e.deleted_by == -1
    && e.LNAME.Trim() == lastName
    && e.FNAME.Trim() == firstName
    && e.TIMECARDDATE == startDate.ToString("MM/dd/yyyy")
    group e by e.LNAME into g
    select new EmployeeHours
    {
        ContractHours = g.Sum(e => e.HRSCONTRACT),
        MillerHours = g.Sum(e => e.HRSSHOWRAIN + e.HRSOTHER),
        TravelHours = g.Sum(e => e.HRSTRAVEL)
    };
pFrenchie