Nullable Integers

Posts   
 
    
gfinstad
User
Posts: 13
Joined: 09-May-2007
# Posted on: 28-Jul-2008 21:15:49   

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:


daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 29-Jul-2008 06:54:36   

We will look into this.

David Elizondo | LLBLGen Support Team
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39866
Joined: 17-Aug-2003
# Posted on: 29-Jul-2008 10:08:08   

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.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39866
Joined: 17-Aug-2003
# Posted on: 29-Jul-2008 11:02:36   

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)

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39866
Joined: 17-Aug-2003
# Posted on: 29-Jul-2008 11:26:28   

frowning

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... flushed

See attached templatebindings file which fixes the problem (regenerate the code. )

Attachments
Filename File size Added on Approval
SD.TemplateBindings.SharedTemplates.NET20.templatebindings 15,220 29-Jul-2008 12:04.46 Approved
Frans Bouma | Lead developer LLBLGen Pro
gfinstad
User
Posts: 13
Joined: 09-May-2007
# Posted on: 29-Jul-2008 19:38:14   

Thank you for the great response time. It works fine now. smile

Jamison avatar
Jamison
User
Posts: 14
Joined: 22-Dec-2006
# Posted on: 29-Jul-2008 22:07:57   

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

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 30-Jul-2008 05:53:58   

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.

David Elizondo | LLBLGen Support Team