- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
LINQ query fails on nested IIF condition
Joined: 16-Dec-2008
Hi,
I'm using the following binaries on .NET 3.5 and LLBL 3.5:
SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll (3.5.13.0108)
SD.LLBLGen.Pro.DQE.SqlServer.NET20.dll (3.5.12.0317)
SD.LLBLGen.Pro.LinqSupportClasses.NET35.dll (3.5.12.1211)
SD.LLBLGen.Pro.QuerySpec.dll (3.5.12.0710)
We have realized that some of our linq queries fail after upgrading to LLBL 3.5. They where working fine in 2.6. This happens when there is nested IIF condition in the select statement on Nullable<Decimal> fields. I know that the following query does not make any sense, I just simplified it for you to be able to reproduce it. As it does not happen on integer fields, I added two decimal columns(Col1 and Col2) to products table in northwind database. I Also replaced the condition part with some true condition as it seems it not the part which causes this issue.
DataAccessAdapter adapter = new DataAccessAdapter("data source=.;initial catalog=northwind;integrated security=SSPI;persist security info=False;packet size=4096");
LinqMetaData md = new LinqMetaData(adapter);
var q = from p in md.Product
select new
{
p.ProductName,
DummySum =
1 > 0
? (1 > 0 ? p.Col1 : 0) - (1 > 0 ? p.Col2 : 0)
: 0
};
var list = q.ToList();
The following exception is thrown:
Argument types do not match
at System.Linq.Expressions.Expression.Condition(Expression test, Expression ifTrue, Expression ifFalse)
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleConditionalExpression(ConditionalExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 1180
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 281
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.InMemoryEvalCandidateFinder.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\InMemoryEvalCandidateFinder.cs:line 143
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpressionList(ReadOnlyCollection`1 listToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 1253
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleNewExpression(NewExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 1389
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 299
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.InMemoryEvalCandidateFinder.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\InMemoryEvalCandidateFinder.cs:line 143
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleLambdaExpression(LambdaExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 1370
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 296
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.InMemoryEvalCandidateFinder.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\InMemoryEvalCandidateFinder.cs:line 143
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleUnaryExpression(UnaryExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 1081
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 242
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.InMemoryEvalCandidateFinder.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\InMemoryEvalCandidateFinder.cs:line 143
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpressionList(ReadOnlyCollection`1 listToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 1253
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleMethodCallExpression(MethodCallExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 1226
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 293
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.InMemoryEvalCandidateFinder.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\InMemoryEvalCandidateFinder.cs:line 143
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.FindInMemoryEvaluationCandidates(Expression toProcess) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 2005
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.PreProcessor.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\PreProcessor.cs:line 167
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.HandleExpressionTree(Expression expression) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\LLBLGenProProviderBase.cs:line 115
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.Execute(Expression expression) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\LLBLGenProProviderBase.cs:line 92
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.System.Linq.IQueryProvider.Execute(Expression expression) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\LLBLGenProProviderBase.cs:line 624
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery`1.Execute() in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\LLBLGenProQuery.cs:line 87
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.5\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\LLBLGenProQuery.cs:line 162
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
.
.
.
.
The query runs fine if the fields are Nullable<Integer> or if I use the p.Col1.Value and p.Col2.Value. We have lots of queries such like this one and using the Value property in not an option for us. The query also runs fine if I omit the subtraction part:
var q = from p in md.Product
select new
{
p.ProductName,
DummySum =
1 <= 0
? (1 > 0 ? p.Col1 : 0)
: 0
};
Thanks.
Query fails on v2.6 as well.
[Test]
public void IIFWithNullableDecimal()
{
using(var adapter = new DataAccessAdapter())
{
var metaData = new LinqMetaData(adapter);
var q = from p in metaData.CreativeAddress
select new
{
p.City,
DummySum =
1 > 0
? (1 > 0 ? p.Latitude : 0) - (1 > 0 ? p.Longitude : 0)
: 0
};
var list = q.ToList();
}
}
Same exception on v2.6 as on v3.5.
The main cause is that the in-memory expression finder wraps one of the IIFs with a Convert to decimal, not a Convert to nullable decimal.
It's a pain to debug as there are 3 nested IIFs, but we'll try to find the cause of this.
Finally found the cause. The method is op_Substraction, which accepts two decimals, not two nullable decimals. The binary expression created (using .NET's Expression.MakeBinary method) returns a Decimal, not a Nullable<Decimal>. This causes the problem. A convert to nullable if there's a difference with the type passed in fixed it.
v3.5 release build is attached. v4 also has this bug, this will be available in the next build.
Filename | File size | Added on | Approval |
---|---|---|---|
SD.LLBLGen.Pro.LinqSupportClasses.NET35.dll | 245,760 | 29-Apr-2013 15:46.00 | Approved |