Error "Non-empty collection required Parameter name: expressions"

Apr 3, 2013 at 9:05 PM
Have a table defined as:
CREATE TABLE itemcounter (counter INTEGER NOT NULL UNIQUE DEFAULT 0)
which holds a single column and single record that is incremented :
Accessor.Execute("UPDATE itemcounter SET counter =(SELECT MAX(counter) FROM itemcounter LIMIT 1) + 1")
The entity:
<DataContract()> _
    <DbTable(Name:="itemcounter ")> _
    Partial Public Class itemcounter 
        Inherits DbEntity(Of itemcounter )
        Implements INotifyPropertyChanged

        <DataMember()> _
        Private m_counter As Integer

        Public Sub New()
        End Sub

        <DbColumn(Name:="counter", IsPrimaryKey:=False, IsDbGenerated:=False)> _
        Public Property counter() As Integer
            Get
                Return m_counter
            End Get
            Set(value As Integer)
                If value = m_counter Then
                    Return
                End If
                m_counter = value
                RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("counter"))
            End Set
        End Property

        Public Event PropertyChanged As PropertyChangedEventHandler Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

    End Class
All my entities where created with the console and work fine (just converted to VB.Net), but the following code throws the error:
Dim count
'  ReadAnonymous works fine ...
count = Accessor.ReadAnonymous(New With { _
     .counter = 0L
      }, "SELECT * FROM [itemcounter ] LIMIT 1").ToList()
Debug.Print(count(0).counter)
' ReadValue also works.
count = Accessor.ReadValue(Of Long)("SELECT counter FROM [itemcounter ]")
Debug.Print(count)
' Any of the following ReadEntity throws the error.
count = Accessor.ReadEntity(Of itemcounter )("SELECT * FROM [itemcounter ] LIMIT 1")
count = Accessor.ReadEntity(Of itemcounter )("SELECT * FROM [itemcounter ]").counter
count = Accessor.ReadEntity(Of itemcounter )("SELECT counter FROM [patientcounter]")
All other entities with or without a PK and more than one field work fine with ReadEntity, just this table is problematic

Any ideas ?

TIA. Oscar
Coordinator
Apr 4, 2013 at 2:56 PM
Edited Apr 4, 2013 at 3:09 PM
Hi Oscar, I tried to recreate your issue in LinqPad but wasn't able to get it to fail. I copied your code directly, and only made a syntactical change here and there. Can you tell me what database you are using? As well, if there is a stack trace from the error, that would be helpful. Also, try to run this code and see if it works for you.
Sub Main
    Dim Accessor = DbFactory.CreateAccessor(DbAccessorType.MsSql, Function() 
            Return New SqlConnection("Integrated Security=SSPI;Initial Catalog=sandbox;Data Source=.") 
        End Function
        )
    
    Accessor.Execute("UPDATE itemcounter SET counter =(SELECT MAX(counter) FROM itemcounter) + 1")
    
    Dim count
    
    '  ReadAnonymous works fine ...
    count = Accessor.ReadAnonymous(New With { _
        .counter = 0L
        }, "SELECT * FROM [itemcounter ]").ToList()
    Debug.Print(count(0).counter)
    
    ' ReadValue also works.
    count = Accessor.ReadValue(Of Integer)("SELECT counter FROM [itemcounter ]")
    Debug.Print(count)
    
    ' Any of the following ReadEntity throws the error.
    count = Accessor.ReadEntity(Of itemcounter )("SELECT * FROM [itemcounter ]")
    Debug.Print(count.counter)
    count = Accessor.ReadEntity(Of itemcounter )("SELECT * FROM [itemcounter ]").counter
    Debug.Print(count)
    count = Accessor.ReadEntity(Of itemcounter )("SELECT counter FROM [itemcounter]")
    Debug.Print(count.counter)
End Sub

<DataContract()> _
    <DbTable(Name:="itemcounter ")> _
    Partial Public Class itemcounter 
        Inherits DbEntity(Of itemcounter )
        Implements INotifyPropertyChanged

        <DataMember()> _
        Private m_counter As Integer

        Public Sub New()
        End Sub

        <DbColumn(Name:="counter", IsPrimaryKey:=False, IsDbGenerated:=False)> _
        Public Property counter() As Integer
            Get
                Return m_counter
            End Get
            Set(value As Integer)
                If value = m_counter Then
                    Return
                End If
                m_counter = value
                RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("counter"))
            End Set
        End Property

        Public Event PropertyChanged As PropertyChangedEventHandler Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

    End Class
Apr 5, 2013 at 11:25 PM
Hi T, forgot to mention that important detail. I'm using SQlite, sorry about that,

Think there is a problem while mapping/casting SQLite columns, saw that in my original ReadValue call you changed cast from Long to Integer; in fact I had it like that but got an error, that is the reason I used Long. Also you did not used the AccessorExtension parameter; which also generates an error; see 'NOTE's' in the following code:
Imports System.Data.SQLite
Imports DrivenDb
Imports System.Runtime.Serialization
Imports System.ComponentModel

Module Module1

    Sub Main()
        Const dbTest As String = "\TestDB.db3"
        Dim dbFile As String = System.AppDomain.CurrentDomain.BaseDirectory() & dbTest

        Dim Accessor = DbFactory.CreateAccessor(DbAccessorType.SqLite, AccessorExtension.All, Function() _
                  New SQLiteConnection("Data Source=" & dbFile))

        Accessor.Execute("CREATE TABLE IF NOT EXISTS itemcounter (counter INTEGER NOT NULL UNIQUE DEFAULT 0); INSERT INTO [itemcounter] SELECT 0 WHERE NOT EXISTS (SELECT * FROM [itemcounter])")
        Accessor.Execute("UPDATE itemcounter SET counter =(SELECT MAX(counter) FROM itemcounter) + 1")

        Dim count

        '  ReadAnonymous works fine ...
        count = Accessor.ReadAnonymous(New With { _
            .counter = 0L
            }, "SELECT * FROM [itemcounter]").ToList()
        Debug.Print(count(0).counter)

        ' ReadValue also works.
        ' NOTE cast MUST be Long, using Integer I get: System.InvalidCastException Error
        count = Accessor.ReadValue(Of Long)("SELECT counter FROM [itemcounter]")
        Debug.Print(count)

        ' Any of the following ReadEntity throws the error.
        ' NOTE if Accessor.Extensions is not set I get this error:
        'DrivenDb.InactiveExtensionException was unhandled
        'Message=DrivenDb extension 'AllowUnmappedColumns' is inactive.  Unable to map column 'counter', type 'Int64' on target type 'itemcounter'.

        ' AFTER adding Accessor.Extension and running again I get:
        'System.ArgumentException was unhandled
        'Message=Non-empty collection required

        count = Accessor.ReadEntity(Of itemcounter)("SELECT * FROM [itemcounter]")
        Debug.Print(count.counter)
        count = Accessor.ReadEntity(Of itemcounter)("SELECT * FROM [itemcounter]").counter
        Debug.Print(count)
        count = Accessor.ReadEntity(Of itemcounter)("SELECT counter FROM [itemcounter]")
        Debug.Print(count.counter)
    End Sub

End Module


<DataContract()> _
    <DbTable(Name:="itemcounter ")> _
Partial Public Class itemcounter
    Inherits DbEntity(Of itemcounter)
    Implements INotifyPropertyChanged

    <DataMember()> _
    Private m_counter As Integer

    Public Sub New()
    End Sub

    <DbColumn(Name:="counter", IsPrimaryKey:=False, IsDbGenerated:=False)> _
    Public Property counter() As Integer
        Get
            Return m_counter
        End Get
        Set(value As Integer)
            If value = m_counter Then
                Return
            End If
            m_counter = value
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("counter"))
        End Set
    End Property

    Public Event PropertyChanged As PropertyChangedEventHandler Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

End Class
And stack trace from all errors:

``` System.InvalidCastException was unhandled
Message=Specified cast is not valid.
Source=DrivenDb
StackTrace:
   at DrivenDb.Base.DbMapper.MapValue[T](IDataReader reader) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbMapper.cs:line 99
   at DrivenDb.Base.DbAccessor.ReadValue[T](String query, Object[] parameters) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbAccessor.cs:line 202
   at Borrar_00.Module1.Main() in F:\Code\VisualStudio\Samples\Borrar_00\Borrar_00\Module1.vb:line 32
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly 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, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
InnerException:

DrivenDb.InactiveExtensionException was unhandled
Message=DrivenDb extension 'AllowUnmappedColumns' is inactive. Unable to map column 'counter', type 'Int64' on target type 'itemcounter'.
Source=DrivenDb
StackTrace:
   at DrivenDb.Base.DbMapper.BuildMapper[T](IDataRecord reader) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbMapper.cs:line 335
   at DrivenDb.Base.DbMapper.GetDeserializer[T](String query, IDataRecord reader) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbMapper.cs:line 287
   at DrivenDb.Base.DbMapper.MapEntities[T](String query, IDataReader reader) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbMapper.cs:line 161
   at DrivenDb.Base.DbMapper.MapEntity[T](String query, IDataReader reader) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbMapper.cs:line 155
   at DrivenDb.Base.DbAccessor.ReadEntity[T](String query, Object[] parameters) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbAccessor.cs:line 280
   at Borrar_00.Module1.Main() in F:\Code\VisualStudio\Samples\Borrar_00\Borrar_00\Module1.vb:line 34
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly 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, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
InnerException:

DrivenDb.InactiveExtensionException was unhandled
Message=DrivenDb extension 'AllowUnmappedColumns' is inactive. Unable to map column 'counter', type 'Int64' on target type 'itemcounter'.
Source=DrivenDb
StackTrace:
   at DrivenDb.Base.DbMapper.BuildMapper[T](IDataRecord reader) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbMapper.cs:line 335
   at DrivenDb.Base.DbMapper.GetDeserializer[T](String query, IDataRecord reader) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbMapper.cs:line 287
   at DrivenDb.Base.DbMapper.MapEntities[T](String query, IDataReader reader) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbMapper.cs:line 161
   at DrivenDb.Base.DbMapper.MapEntity[T](String query, IDataReader reader) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbMapper.cs:line 155
   at DrivenDb.Base.DbAccessor.ReadEntity[T](String query, Object[] parameters) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbAccessor.cs:line 280
   at Borrar_00.Module1.Main() in F:\Code\VisualStudio\Samples\Borrar_00\Borrar_00\Module1.vb:line 37
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly 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, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
InnerException:

System.ArgumentException was unhandled
Message=Non-empty collection required
Parameter name: expressions
Source=System.Core
ParamName=expressions
StackTrace:
   at System.Dynamic.Utils.ContractUtils.RequiresNotEmpty[T](ICollection`1 collection, String paramName)
   at System.Linq.Expressions.Expression.Block(Expression[] expressions)
   at DrivenDb.Base.DbMapper.BuildMapper[T](IDataRecord reader) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbMapper.cs:line 343
   at DrivenDb.Base.DbMapper.GetDeserializer[T](String query, IDataRecord reader) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbMapper.cs:line 287
   at DrivenDb.Base.DbMapper.MapEntities[T](String query, IDataReader reader) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbMapper.cs:line 161
   at DrivenDb.Base.DbMapper.MapEntity[T](String query, IDataReader reader) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbMapper.cs:line 155
   at DrivenDb.Base.DbAccessor.ReadEntity[T](String query, Object[] parameters) in d:\Code\CodePlex\DrivenDb\DrivenDb\Language\Base\DbAccessor.cs:line 280
   at Borrar_00.Module1.Main() in F:\Code\VisualStudio\Samples\Borrar_00\Borrar_00\Module1.vb:line 41
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly 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, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
Coordinator
Apr 6, 2013 at 2:15 PM
I done some research on this. It appears that using a .net Integer type on a SqLite data contract is probably a bad idea. The links below suggest that regardless of how they are stored (which can be variable per value)

http://stackoverflow.com/questions/7337882/sqlite-and-integer-types-int-integer-bigint

, they are upcast to long upon retrieval.

http://stackoverflow.com/questions/13832103/sqlite-integer-value-bytes

I need to do a little more reading. but I believe the workaround for you is to use longs on your data contracts and for me to not generate data contracts with int type properties. I'll be moving this to the issue list.
Coordinator
Apr 6, 2013 at 2:15 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.