- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
Testing on null instance causes an exception.
Joined: 05-Sep-2006
Hi,
Consider the following Linq query:
UserParameter param1 = null;
var query = from emp in metaData.Employee
where param1 == null || emp.ID == param1.ID select emp;
In this query I want to read only the employee with the ID specified by the user. If the user specifies no ID (param1 == null) I want to return all employees.
This works in Linq to Objects, because due to the shortcut OR, param1.ID is not evaluated if param1 == null. In Linq to LLBLGen I get a NullReferenceException, probably because param1.ID is evaluated always, even if param1 == null.
Stack trace:
System.NullReferenceException: Object reference not set to an instance of an object.
at SD.LLBLGen.Pro.LinqSupportClasses.LinqUtils.ObtainRealValueFromConstantWrapped(MemberExpression expressionToHandle, Expression memberContainer)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleMemberIsPartOfConstant(MemberExpression expressionToHandle, Expression memberContainer)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleMemberExpression(MemberExpression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleExpression(Expression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleInMemoryEvalCandidateExpression(InMemoryEvalCandidateExpression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleExpression(Expression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleBinaryExpression(BinaryExpression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleBinaryExpression(BinaryExpression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleBinaryExpressionBooleanOperator(BinaryExpression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleExpression(Expression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleBinaryExpression(BinaryExpression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleBinaryExpression(BinaryExpression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleBinaryExpressionBooleanOperator(BinaryExpression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleExpression(Expression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleLambdaExpression(LambdaExpression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleExpression(Expression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleMethodCallWhere(MethodCallExpression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleQueryableExtensionMethod(MethodCallExpression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleMethodCallPerType(MethodCallExpression expressionToHandle, Type declaringType)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleMethodCallExpression(MethodCallExpression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleExpression(Expression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleAggregateFunctionMethodCall(MethodCallExpression expressionToHandle, AggregateFunction function)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleQueryableExtensionMethod(MethodCallExpression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleMethodCallPerType(MethodCallExpression expressionToHandle, Type declaringType)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleMethodCallExpression(MethodCallExpression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleExpression(Expression expressionToHandle)
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.HandleExpressionTree(Expression expression)
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.Execute(Expression expression)
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.System.Linq.IQueryProvider.Execute<TResult>(Expression expression)
at System.Linq.Queryable.Count<TSource>(IQueryable`1 source)
at IPParking.ParkBase.TestSuite.EmployeeFixture.Test2()
Kind regards,
Patrick
Please try the following, otherwise is not supported.
UserParameter param1 = null;
var query = null;
if(param1 == null)
{
query = from emp in metaData.Employee
select emp;
}
else
{
query = from emp in metaData.Employee
where emp.ID == param1.ID
select emp;
}
Joined: 05-Sep-2006
Walaa wrote:
Please try the following, otherwise is not supported.
UserParameter param1 = null; var query = null; if(param1 == null) { query = from emp in metaData.Employee select emp; } else { query = from emp in metaData.Employee where emp.ID == param1.ID select emp; }
Well, yeah, that is quite obvious , but unfortunately normally my queries are not that simple and it is error prone when I have to make a change to the query and thus to all variants of it. Not to mention when more than 1 parameters are nullable.
Too bad it is not supported.
Thanks anyway,
Patrick
You have to take this route as the constant predicate (param==null, which resolves to 'true', a constant predicate) is not supported in our query system and the provider doesn't optimize these away.
I don't agree it's more error prone, you effectively test for nullability, which is IMHO a good thing. You can use the predicate builder class (see http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=14224) for dynamically append where clauses easily, so it shouldn't be that hard to write the queries in a more complex scenario.