- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
Nullable Integers
Joined: 09-May-2007
I have an integer field that allows null values. I get the error below with the following query...
Public Shared Function GetPacketFormFieldsByPacketFormIdent(ByVal packetForm As Integer) As List(Of PacketFormField)
Dim PacketFormFields As New List(Of PacketFormField)
Using adapter As New DataAccessAdapter
Dim metaData As New LinqMetaData(adapter)
Dim q = From pf In metaData.PacketForm _
Where pf.PacketFormIdent = packetForm _
Join pff In metaData.PacketFormField On pf.PacketFormIdent Equals pff.PacketFormIdent _
Select pf.PacketFormIdent, pf.FormNumber, pf.PacketFormStatusIdent, pff.FieldCode, pff.FieldTypeIdent, pff.Text, pff.IsChecked, pff.OptionIndex, pff.DateTime, pff.GridRow, pff.GridColumn
Dim LastPacketFormIdent As Integer
Dim LastFieldCode As String = ""
Dim LastFieldTypeIdent As Integer = 0
Dim LastText As String = ""
Dim LastIsChecked As Boolean
Dim LastDateTime As DateTime
Dim LastOptionIndex As Integer
Dim LastGridRow As Integer
Dim LastGridColumn As Integer
For Each pff In From pf In q
If pff.PacketFormIdent <> LastPacketFormIdent Then
PacketFormFields.Add(New PacketFormField With {.PacketFormFieldIdent = LastPacketFormIdent, .FieldCode = LastFieldCode, .FieldTypeIdent = LastFieldTypeIdent, .Text = LastText, .IsChecked = LastIsChecked, .DateTime = LastDateTime, .OptionIndex = LastOptionIndex, .GridRow = LastGridRow, .GridColumn = LastGridColumn})
End If
LastPacketFormIdent = pff.PacketFormIdent
LastFieldCode = pff.FieldCode
LastFieldTypeIdent = pff.FieldTypeIdent
LastText = pff.Text
LastIsChecked = pff.IsChecked.Value
LastDateTime = pff.DateTime.Value
LastOptionIndex = pff.OptionIndex.Value
LastGridRow = pff.GridRow.Value
LastGridColumn = pff.GridColumn.Value
Next
End Using
Return PacketFormFields
End Function
Is there something that I need to do to handle nullable values?
System.ArgumentException was unhandled
Message="Argument type 'System.Int32' does not match the corresponding member type 'System.Nullable`1[System.Int32]'"
Source="System.Core"
StackTrace:
at System.Linq.Expressions.Expression.ValidateNewArgs(ConstructorInfo constructor, ReadOnlyCollection`1& arguments, ReadOnlyCollection`1 members) at System.Linq.Expressions.Expression.New(ConstructorInfo constructor, IEnumerable`1 arguments, IEnumerable`1 members) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleNewExpression(NewExpression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.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.GenericExpressionHandler.HandleProjectionExpression(ProjectionExpression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleJoinExpression(JoinExpression expressionToHandle) at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.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.GenericExpressionHandler.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.LLBLGenProQuery`1.Execute() at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() at MedfordSchoolDistrict.SPEEDeBl.PacketManager.GetPacketFormFieldsByPacketFormIdent(Int32 packetForm) in C:\Production Source Code\SPEEDe\SPEEDeBl\PacketManager.vb:line 47 at SPEEDeMain.frmSpecialEdFormList.LoadPacketForm() in C:\Production Source Code\SPEEDe\SPEEDeMain\frmSpecialEdFormList.vb:line 293 at SPEEDeMain.frmSpecialEdFormList.btnLoadForm_Click(Object sender, EventArgs e) in C:\Production Source Code\SPEEDe\SPEEDeMain\frmSpecialEdFormList.vb:line 298 at System.Windows.Forms.Control.OnClick(EventArgs e) at Infragistics.Win.UltraControlBase.OnClick(EventArgs e) at Infragistics.Win.Misc.UltraButtonBase.OnClick(EventArgs e) at Infragistics.Win.Misc.UltraButton.OnMouseUp(MouseEventArgs e) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData) at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.Run(ApplicationContext context) at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine) at SPEEDeMain.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81 at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args) at System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel) at System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly() at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData) at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Likely related to how VB.Net's compiler produces expression trees. In C# there's no problem using nullables, we did add code for vb.net's compiler specific trees as well, but perhaps in this case the tree looks different. (yes, it's that silly, different compilers, different tree structure and elements, different meaning and no documentation from ms!)
Will check it out.
Can't reproduce it.
<Test()> _
Public Sub NullableFieldInProjection()
Using adapter As New DataAccessAdapter()
Dim metaData As New LinqMetaData(adapter)
Dim q = From o In metaData.Order _
Join e In metaData.Employee On o.EmployeeId Equals e.EmployeeId _
Select o.EmployeeId, o.OrderId, e.LastName
Dim counter As Integer = 0
For Each v In q
counter += 1
Assert.IsTrue(v.EmployeeId.HasValue)
Next
Assert.AreEqual(818, counter)
End Using
End Sub
o.EmployeeId is nullable (integer).
Query above produces a proper SQL query without errors.
What field is nullable in your query and did you try it with the latest build of the runtime libraries? Please provide as much information as possible so we can reproduce this, as with the information you've currently given we can't.
(also using .Value on the nullable fields works).
I have to add, that the generated code used is C# generated. I'll try with VB.NET code generated to see if that makes a difference (you'll never know)
With VB.NET generated code.... it indeed crashes!
Amazing... Looking into it.
(edit) expression trees look exactly the same... bizar.
(edit) I think I found it. It's a bug in the VB.NET templates. The FieldInfoProvider class doesn't specify Nullable<T> types for nullable fields, the C# template does, and this type is the core type specified in an entityfield object (DataType property) which is used inside the Linq provider.
(edit) bug in template bindings .NET 2.0 for VB.NET, they point to the .NET 1.x templates for 2 templateids...
See attached templatebindings file which fixes the problem (regenerate the code. )
Filename | File size | Added on | Approval |
---|---|---|---|
SD.TemplateBindings.SharedTemplates.NET20.templatebindings | 15,220 | 29-Jul-2008 12:04.46 | Approved |
Thanks gfinstad! We ran into this same problem today. I've tried Otis's fix, but now the error is slightly different. My statement is much simpler. It is just joining on a nullalble integer column.
Public Function GetResults() As EntityCollection(Of NoteEntity)
Using da As New DataAccessAdapter
Dim md As New LinqMetaData(da)
Dim theResults = _
From r In md.Note _
Where r.ID = _FindID _ '<---- ID is nullable
Take TopRows _
Select r
Return CType(theResults, ILLBLGenProQuery).Execute(Of EntityCollection(Of NoteEntity))() '<---- Line 123
End Using
End Function
ystem.InvalidOperationException: The binary operator Equal is not defined for the types 'System.Nullable`1[System.Int32]' and 'System.Int32'.
at System.Linq.Expressions.Expression.GetEqualityComparisonOperator(ExpressionType binaryType, String opName, Expression left, Expression right, Boolean liftToNull)
at System.Linq.Expressions.Expression.Equal(Expression left, Expression right, Boolean liftToNull, MethodInfo method)
at System.Linq.Expressions.Expression.MakeBinary(ExpressionType binaryType, Expression left, Expression right, Boolean liftToNull, MethodInfo method, LambdaExpression conversion)
at System.Linq.Expressions.Expression.MakeBinary(ExpressionType binaryType, Expression left, Expression right, Boolean liftToNull, MethodInfo method)
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.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.HandleMethodCallTake(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.HandleMethodCallSelect(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.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.LLBLGenProQuery`1.Execute()
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery`1.SD.LLBLGen.Pro.LinqSupportClasses.ILLBLGenProQuery.Execute<TResult>()
at AppRiver.ARBO.BLL.Notes.NoteSearch.GetResults() in NoteSearch.vb: line 123
at AppRiver.ARBO.BLL.UnitTests.NoteTest.TestNoteSearch() in NoteTest.vb: line 31
We came up with a work-around.
Public Function GetResults() As EntityCollection(Of NoteEntity)
Using da As New DataAccessAdapter
Dim md As New LinqMetaData(da)
Dim theResults = _
From r In md.Note _
Where CInt(r.ID.Value) = CInt(_FindID.Value) _
Take TopRows _
Select r
Return CType(theResults, ILLBLGenProQuery).Execute(Of EntityCollection(Of NoteEntity))()
End Using
End Function
Sound like that is related to this:
VB.NET users should use the .Value property of Nullable(Of T) typed fields instead of just the field in filter expressions, like expressions in the Where clause. The VB.NET compiler introduces coalesce statements on these boolean expressions if it detects a Nullable(Of T) typed element in the expression which are useless and which bloat the query unnecessary. Linq to LLBLGen Pro strips off these needless coalesce expressions if it runs into one of them (except in the projection (select)), however it can be it can't make the proper decision and the query fails.