Nullable Date in where clause

Posts   
 
    
nfoscolos
User
Posts: 12
Joined: 20-Sep-2007
# Posted on: 18-Mar-2008 23:20:53   

Hi,

We are struggling with the following query

                var d =
                        (from b in metadata.EqBasket
                         where (b.Status == "COMP")
                         && (b.ReleasedDate >= new DateTime(2008,3,17))
                         select b.BasketNo);

The problem is that ReleasedDate is Nullable<DateTime>.

The error we get is confused

"Expression of type 'System.Nullable`1[System.DateTime]' cannot be used for parameter of type 'System.DateTime' of method 'Boolean op_GreaterThanOrEqual(System.DateTime, System.DateTime)'"

We also tried b.ReleasedDate.Value >= ... b.ReleasedDate.Value.CompareTo(DateTime.Parse("3/17/2008")) ... which (unsuprisingly) did not workcry

The stack trace is

  at System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodInfo method, ReadOnlyCollection`1& arguments)
   at System.Linq.Expressions.Expression.ValidateCallArgs(Expression instance, MethodInfo method, ReadOnlyCollection`1& arguments)
   at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)
   at System.Linq.Expressions.Expression.Call(MethodInfo method, Expression[] arguments)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleBinaryExpression(BinaryExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 204
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleBinaryExpressionBooleanOperator(BinaryExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 989
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 270
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 132
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleBinaryExpression(BinaryExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 1081
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleBinaryExpression(BinaryExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 198
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleBinaryExpressionBooleanOperator(BinaryExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 989
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 270
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 132
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleLambdaExpression(LambdaExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 1362
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 295
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 132
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleMethodCallWhere(MethodCallExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 1234
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleQueryableExtensionMethod(MethodCallExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 1461
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleMethodCallPerType(MethodCallExpression expressionToHandle, Type declaringType) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 1311
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleMethodCallExpression(MethodCallExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 572
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 292
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 132
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleMethodCallSelect(MethodCallExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 1199
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleQueryableExtensionMethod(MethodCallExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 1433
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleMethodCallPerType(MethodCallExpression expressionToHandle, Type declaringType) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 1311
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleMethodCallExpression(MethodCallExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 572
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 292
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 132
   at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.HandleExpressionTree(Expression expression) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\LLBLGenProProviderBase.cs:line 114
   at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.Execute(Expression expression) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\LLBLGenProProviderBase.cs:line 91
   at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.System.Linq.IQueryProvider.Execute(Expression expression) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\LLBLGenProProviderBase.cs:line 662
   at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery`1.Execute() in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\LLBLGenProQuery.cs:line 84
   at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.6 .NET 2.x\LinqSupportClasses\LLBLGenProQuery.cs:line 129
   at System.Linq.SystemCore_EnumerableDebugView`1.get_Items()

What are we doing wrong?

thanks,

Nick

twaindev avatar
twaindev
User
Posts: 178
Joined: 08-Oct-2007
# Posted on: 18-Mar-2008 23:40:23   

Hi,

You have to cast the nullable DateTime to a normal DateTime:


var d = (from b in metadata.EqBasket
             where (b.Status == "COMP")
             && ((DateTime)b.ReleasedDate >= new DateTime(2008,3,17))
             select b.BasketNo);

HTH

nfoscolos
User
Posts: 12
Joined: 20-Sep-2007
# Posted on: 19-Mar-2008 13:36:57   

Thanks!

that did it.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 19-Mar-2008 13:59:49   

Or: b.ReleasedDate.Value >= new DateTime(2008,3,17))

simple_smile I'll see if I can make the error handling better in this scenario or even solve it (as the nullable type has no meaning in the query)

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 20-Mar-2008 17:45:29   

I've added code to handle the initial scenario.

It's a dumb thing though... the Linq expression (.net framework code!) code throws up as it can't deal with a Nullable<T> typed value for the method call which accepts T typed parameters. While this is logical (.Value has to be passed), the problem is that the code does compile. The reason is that this is correct code:


int? foo = 0;
bool areEqual = (foo == 3);

so it should work in linq expressions as well: the problem is however that the linq expression are more strict, or better: more stupid, as they see Nullable<T> and T as different types.

The second scenario, namely: b.ReleasedDate.Value >= new DateTime(2008,3,17)) still fails, as this re-introduces the nullable<DateTime>, as b.ReleasedDate.Value is evaluated to the entityfield ReleasedDate, which is a nullable datetime, so it crashes.

I'll add some code which will check this in a generic way and will add convert expressions to the query if necessary (so the expression tree is constructable again. These convert expressions are filtered out later or kept, if necessary)

(edit) Both scenario's are now working, fixed in next build simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Jez
User
Posts: 198
Joined: 01-May-2006
# Posted on: 22-Mar-2008 21:55:57   

Possibly a related issue, but this query:

var query = from o in meta.Order
        where o.ShippedDate == null
        select o;

also fails with this exception:

Expression of type 'System.Nullable`1[System.DateTime]' cannot be used for parameter of type 'System.DateTime' of method 'Boolean op_Equality(System.DateTime, System.DateTime)'

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 24-Mar-2008 11:38:00   

With the same query I get a different error with the latest build (the reworked projection pipeline version). It tries to pass a db functioncall to the db.. Will look into it.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 24-Mar-2008 11:57:24   

Ok, fixed in next build. MS really messed up with nullable types also in linq expressions: they introduced some weird parameters called 'IsLifted' and 'IsLiftedToNull'. The documentation is sparse on them, and especially when they occur and what to do with them. The test on these was a bit too strict so it didn't anticipated IsLifted==true && IsLiftedToNull==false. Now it does (I build a more generic version of implicit cast testing from/to nullable types.

Frans Bouma | Lead developer LLBLGen Pro
johnman
User
Posts: 10
Joined: 11-Mar-2007
# Posted on: 19-Apr-2008 14:16:10   

Otis wrote:

Ok, fixed in next build. MS really messed up with nullable types also in linq expressions: they introduced some weird parameters called 'IsLifted' and 'IsLiftedToNull'. The documentation is sparse on them, and especially when they occur and what to do with them. The test on these was a bit too strict so it didn't anticipated IsLifted==true && IsLiftedToNull==false. Now it does (I build a more generic version of implicit cast testing from/to nullable types.

Hi,

I had a nullable guid which was having a similar issue (i.e. couldn't run the query). Don't know if you had added support for nullable guids as well.

John

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 19-Apr-2008 16:03:07   

Yes, and the error you ran into is caused by the same thing.

We hope to release a new beta build on monday.

Frans Bouma | Lead developer LLBLGen Pro