Search code examples
c#.netoracle11gdatareader

dataReader.GetValue(i) throws System.InvalidOperationException


.Net 4.5 / WPF / MVVM / ADO.Net / Oracle 11g / Oracle.DataAccess.Client

Using : IDataReader Interface


So, I have sealed BusinessObject builder class, which takes in a DataReader object, converts the data inside each field in that DataReader based on PropertyMap - the PropertyMap is retrieved from a class - and returns a ListItem.

This ListItem is then added to a List and the List is then used to process the data, display the data etc on the View.

The whole process is working perfect with in other places inside my application and today I was trying to use the BusinessObject builder process to convert a new set of records to a List and use it in my DashBoard.

The propertymap for this entiry is as below.

-       pinfo   Count = 9   System.Collections.Generic.Dictionary<string,System.Reflection.PropertyInfo>
    +       [0] {[LATEST_LOAD_TIME, System.DateTime LATEST_LOAD_TIME]}  
    +       [1] {[LAST_DELIVERY, System.DateTime LAST_DELIVERY]}    
    +       [2] {[MAXVALDATE, System.DateTime MAXVALDATE]}  
    +       [3] {[MINVALDATE, System.DateTime MINVALDATE]}  
    +       [4] {[COMPLETED, Int32 COMPLETED]}  
    +       [5] {[FAILED, Int32 FAILED]}    
    +       [6] {[IN_PROGRESS, Int32 IN_PROGRESS]}  
    +       [7] {[NOT_STARTED, Int32 NOT_STARTED]}  
    +       [8] {[TOTAL, Int32 TOTAL]}

But, as soon as the process hits the if () clause below

for (int i = 0; i < dataReader.FieldCount; i++)
{
    if (dataReader.GetValue(i) != DBNull.Value)
    {
        try
        {   

it throws an System.InvalidOperationException exception. See the full exception details below.

+       dataReader  {Oracle.DataAccess.Client.OracleDataReader} System.Data.IDataReader {Oracle.DataAccess.Client.OracleDataReader}
-       dataReader.GetValue(i)  'dataReader.GetValue(i)' threw an exception of type 'System.InvalidOperationException'  object {System.InvalidOperationException}
    -           base    {"Operation is not valid due to the current state of the object."}  System.SystemException {System.InvalidOperationException}
        -       base    {"Operation is not valid due to the current state of the object."}  System.Exception {System.InvalidOperationException}
            +       Data    {System.Collections.ListDictionaryInternal} System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
                        HelpLink    null    string
                        HResult -2146233079 int
            +       InnerException  null    System.Exception
                        Message "Operation is not valid due to the current state of the object."    string
                        Source  "Oracle.DataAccess" string
                        StackTrace  "   at Oracle.DataAccess.Client.OracleDataReader.GetValue(Int32 i)" string
            -       TargetSite  {System.Object GetValue(Int32)} System.Reflection.MethodBase {System.Reflection.RuntimeMethodInfo}
            +       [System.Reflection.RuntimeMethodInfo]   {System.Object GetValue(Int32)} System.Reflection.RuntimeMethodInfo
            -       base    {System.Object GetValue(Int32)} System.Reflection.MemberInfo {System.Reflection.RuntimeMethodInfo}
            +       CustomAttributes    Count = 0   System.Collections.Generic.IEnumerable<System.Reflection.CustomAttributeData> {System.Collections.ObjectModel.ReadOnlyCollection<System.Reflection.CustomAttributeData>}
            +       DeclaringType   {Name = "OracleDataReader" FullName = "Oracle.DataAccess.Client.OracleDataReader"}  System.Type {System.RuntimeType}
                        MemberType  Method  System.Reflection.MemberTypes
                        MetadataToken   100665607   int
            +       Module  {Oracle.DataAccess.dll} System.Reflection.Module {System.Reflection.RuntimeModule}
                    Name    "GetValue"  string
            +       ReflectedType   {Name = "OracleDataReader" FullName = "Oracle.DataAccess.Client.OracleDataReader"}  System.Type {System.RuntimeType}
                        Attributes  FamANDAssem | Family | Virtual | HideBySig  System.Reflection.MethodAttributes
                        CallingConvention   Standard | HasThis  System.Reflection.CallingConventions
                        ContainsGenericParameters   false   bool
                        IsAbstract  false   bool
                        IsAssembly  false   bool
                        IsConstructor   false   bool
                        IsFamily    false   bool
                        IsFamilyAndAssembly false   bool
                        IsFamilyOrAssembly  false   bool
                        IsFinal false   bool
                        IsGenericMethod false   bool
                        IsGenericMethodDefinition   false   bool
                        IsHideBySig true    bool
                        IsPrivate   false   bool
                        IsPublic    true    bool
                        IsSecurityCritical  true    bool
                        IsSecuritySafeCritical  true    bool
                        IsSecurityTransparent   false   bool
                        IsSpecialName   false   bool
                        IsStatic    false   bool
                        IsVirtual   true    bool
            +       MethodHandle    {System.RuntimeMethodHandle}    System.RuntimeMethodHandle
                        MethodImplementationFlags   IL  System.Reflection.MethodImplAttributes
            +       Non-Public members      
            +       Static members      
            +       Non-Public members  

I know the exception says

Message "Operation is not valid due to the current state of the object."

and I thought the DataReader might be closed, but it is not. See below the status

-       dataReader  {Oracle.DataAccess.Client.OracleDataReader} System.Data.IDataReader {Oracle.DataAccess.Client.OracleDataReader}
    +       [Oracle.DataAccess.Client.OracleDataReader] {Oracle.DataAccess.Client.OracleDataReader} Oracle.DataAccess.Client.OracleDataReader
            Depth   0   int
            IsClosed    false   bool
            RecordsAffected -1  int
    -       Results View    Expanding the Results View will enumerate the IEnumerable   
        -       [0] {System.Data.Common.DataRecordInternal} object {System.Data.Common.DataRecordInternal}
        -       base    {System.Data.Common.DataRecordInternal} System.Data.Common.DbDataRecord {System.Data.Common.DataRecordInternal}
                FieldCount  9   int
                FieldCount  9   int

Also, please see that the DataReader record does contain values

-       _values {object[9]} object[]
                [0] 0   object {decimal}
                [1] 0   object {decimal}
                [2] 0   object {decimal}
                [3] 0   object {decimal}
                [4] 1502    object {decimal}
        +       [5] {}  object {System.DBNull}
        +       [6] {}  object {System.DBNull}
        +       [7] {5/5/2015 12:00:00 AM}  object {System.DateTime}
        +       [8] {4/30/2015 12:00:00 AM} object {System.DateTime}
        +       [1] {System.Data.Common.DataRecordInternal} object {System.Data.Common.DataRecordInternal}
        +       [2] {System.Data.Common.DataRecordInternal} object {System.Data.Common.DataRecordInternal}

Initially the first item in the data record was of type DateTime and I thought the error might be because of that. So I changed the column ordinal to put a record of type int as the first item - but the exception is still thrown.

I think it has to do something with the GetValue() method, but not sure.

Anyone have any idea what possibly might be the issue and any advice / help?

Sorry for the long code / exception samples, but don't want to miss out any details...


Solution

  • GetValue is supposed to return DBNull for null values but try this

    if (!dataReader.isDBNull(i)) 
    {
        ...
    }
    

    SqlDataReader.IsDBNull

    or try this syntax

    if (!DBNull.Value.Equals(dataReader.GetValue(i)))