- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
Where clause can't be converted to predicate expression
llbl=2.6, sqlServer=2007, targetLanguate=vb.net, templateGroup=adapter, .net=3.5
Hello, I am really excited about the new release and I am trying to get started testing so we can convert everything over. I ran into this error and I figure I must be doing something wrong here.
I get the following error: The binary expression '(CompareString([508], "123 Main Street", False) = 0)' can't be converted to a predicate expression.
when I run this code:
Dim adapter As New LMTEST.LLBL.DatabaseSpecific.DataAccessAdapter
Dim meta As New LMTEST.LLBL.Linq.LinqMetaData(adapter)
Dim q = From s In meta.Shipment _
Where s.Address = "123 Main Street" _
Select s
'Error happens on next line
For Each row In q
Console.WriteLine(row.Address)
Next
I must be doing something wrong here when working with linq and strings, it works when I change it to
Dim q = From s In meta.Shipment _
Where s.ShipmentID = 1 _
Select s
The Shipment Entity's Address Field is type System.String not a Nullable(Of String)
It also worked when i tried the same thing in c# using my vb.net generated code.
this code worked fine:
var q = from s in meta.Shipment
where s.Address == "123 Main Street"
select s;
here is the stack trace:
" at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder. HandleBinaryExpressionSeparateOperands(BinaryExpression expressionToHandle, Expression leftSide, Expression rightSide) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder. HandleBinaryExpressionBooleanOperator(BinaryExpression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder. HandleExpression(Expression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder. HandleLambdaExpression(LambdaExpression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExpression(Expression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder. HandleWhereExpression(WhereExpression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExpression(Expression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler. HandleSelectExpression(SelectExpression expressionToHandle, SelectExpression newInstance) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleSelectExpression( SelectExpression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleSelectExpression( SelectExpression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression( Expression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.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(Expression expression) at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery1.Execute() at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery
1.System.Collections.Generic.IEnumerable<T>. GetEnumerator() at ConsoleApplication1.Module1.Main() in C:\Projects\LLBL26test\ConsoleApplication1\Module1.vb:line 12 at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()"
I think this is caused by a VB.NET specific thing. The VB.NET compiler creates different expression trees sometimes, but it's unknown when it generates which differences compared to the C# compiler (yes, MS did a lousy job in that department), so these issues are unfortunately hard to track down.
We wrote everything with C#, and then tried a lot of edge things in VB.NET as well, where we thought it might be different. Obviously we skipped the most simple one of all, the one you ran into
It seems it calls a CompareString() function, very strange. I'll try to reproduce it and fix it.
I think Where s.Address.Equals("123 Main Street") should work in VB.NET though.
Expect a fix thursday.
Equals indeed works, '=' doesn't, because the VB compiler doesn't create a simple BinaryExpression with an 'Equal' operator, or with an op_equals method call, but it generates a CompareString() method call.
There are three areas which are problematic, according to the linq to sql sourcecode (sorry MS, but you should document this better).
1) stringfield = stringvalue -> will result in Microsoft.VisualBasic.CompilerServices.Operators.CompareString call. The documentation of this method says: 'returns 0 if strings do NOT match', however the tree compares the result with 0, and should be equal if the strings match... testing it with linq to sql suggests the documentation is wrong. 2) the LIKE operator in VB (I don't know what that does, will find out) 3) some conversion routines (I suspect CInt() and the like)
Ok: - CompareString() -> fixed in next build. - LikeString() etc. (VB.NET Like operator) -> not supported, one should use .StartsWith(), .EndsWith() or .Contains() to produce LIKE queries. A proper exception is now thrown - CInt() etc. are now detected and converted to proper ConvertExpressions.
Available in next build.