无法将类型为'System.Int32'的对象转换为类型'System.String'

8
我在下面的代码中偶尔得到一个'无法将类型为'System.Int32'的对象强制转换为类型'System.String'的异常。它可以正常工作9/10次,但随机地会抛出一个异常。我确保传递的SettingID没有空值,并且表中的数据总是存在于这个SettingID中,而我总是以Integer的形式传递SettingID。
你有什么想法这段代码有什么问题吗?
以下是异常信息:
System.InvalidCastException: 无法将类型为'System.Int32'的对象强制转换为类型'System.String'。 在 System.Data.SqlClient.SqlBuffer.get_String() 在 Read_CPT_Setting(ObjectMaterializer`1 ) 在 System.Data.Linq.SqlClient.ObjectReaderCompiler.ObjectReader`2.MoveNext() 在 System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source) 在 System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source) 在 CPT.Service.SettingLinqProvider.GetSettingFromDBById(Int32 SettingId)
代码:
Public Function GetSettingFromDBById(ByVal SettingId As Integer) As ReturnObject(Of Model.ISettingBase) 

    Dim retObj As New ReturnObject(Of Model.ISettingBase)
    Dim dbSetting As CPT_Setting

    Try
        Dim _cptDB As New CPT.Data.CPTLinqRepository.DB(_connString)
        Using _cptDB

             dbSetting = (From s In context.CPT_Settings _
                                  Where s.SettingId = settingId _
                                  Select s).SingleOrDefault

            If dbSetting IsNot Nothing Then
                retObj.ReturnValue = Mapping.Setting.MapDBToModel(dbSetting)
            End If

        End Using
    Catch ex As Exception
        retObj.ReturnValue = Nothing
        retObj.AddErrorMessage("Error returning the site: " & ex.Message)
        _log.Error(ex.Message, _userId, ex)
    End Try

    If retObj.ReturnValue Is Nothing Then
        retObj.AddErrorMessage("Site Not Found.")
    End If

    Return retObj
End Function

我已经在上面的代码中加入了一些日志记录,每行代码之后都有。
Public Function GetSettingFromDBById(ByVal SettingId As Integer) As ReturnObject(Of Model.ISettingBase) 

    Dim retObj As New ReturnObject(Of Model.ISettingBase)
    Dim dbSetting As CPT_Setting
    Dim SettingsList As New List(Of CPT_Setting)

    Dim errStr As String = " ENTER "

    Try
        Dim _cptDB As New CPT.Data.CPTLinqRepository.DB(_connString)
        Using _cptDB
            errStr &= " - Inside Context "
            If _cptDB Is Nothing Then
                errStr &= " - With Context is Nothing "
                _log.Error("Unusual Object - Unable to create connection object - Object is NOTHING", _userId)
            End If

            If System.DBNull.Value.Equals(_cptDB) Then
                errStr &= " - With Context is NULL "
                _log.Error("Unusual Object - Unable to create connection object - Object is NULL", _userId)
            End If

            errStr &= " - Querying With SettingID = " & SettingId.ToString()

            Dim dbSettingTemp = (From s In context.CPT_Settings _
                              Where s.SettingId = settingId _
                              Select s)

            If dbSettingTemp Is Nothing Then
                errStr &= " -- Nothing is returned from DB - Object is NOTHING -- "
                _log.Error(errStr, _userId)
            End If
            If System.DBNull.Value.Equals(dbSettingTemp) Then
                errStr &= " -- Nothing is returned from DB - Object is NULL -- "
                _log.Error(errStr, _userId)
            End If

            errStr &= " -- Before SingleOrDefault -- "
            dbSetting = dbSettingTemp.SingleOrDefault
            errStr &= " -- After SingleOrDefault -- "

            If dbSetting IsNot Nothing Then
                If System.DBNull.Value.Equals(dbSetting) Then
                    errStr &= " - NULL OBJECT RETURNED - Before Mapping "
                    _log.Error("Unusual Exception - NULL OBJECT RETURNED " & errStr, _userId)
                End If

                retObj.ReturnValue = Mapping.Setting.MapDBToModel(dbSetting)
                errStr &= " - After Mapping With SettingID=" & dbSetting.SettingId.ToString() & " SettingName=" & dbSetting.SettingName.ToString() & " StartDate=" & dbSetting.StartDate.ToShortDateString() & " EndDate=" & dbSetting.EndDate.ToShortDateString()

            Else
                errStr &= " - DBSetting Is Nothing "
                _log.Error("Unusual Object - No Data Retrieved for SettingID=" & SettingId.ToString() & " " & errStr, _userId)
            End If

        End Using
    Catch ex As Exception
        retObj.ReturnValue = Nothing
        retObj.AddErrorMessage("Error returning the site: " & ex.Message)
        _log.Error("Unusual Exception for SettingID=" & SettingId.ToString() & "--" & errStr & "--" & ex.Message, _userId, ex)
    End Try

    If retObj.ReturnValue Is Nothing Then
        retObj.AddErrorMessage("Site Not Found.")
        _log.Info("Unusual Object - MRDD Solutions - No Data Retrieved for SettingID=" & SettingId.ToString() & " " & errStr, _userId)
    End If

    Return retObj
End Function

注意:DB中包含以下消息中提到的所有settingIDs的行。

结果:

场景1:

异常对象-未检索到SettingID = 142176的数据 ENTER-在上下文内-使用SettingID = 142176进行查询-- Before SingleOrDefault -- - After SingleOrDefault -- - DBSetting为null

异常对象-MRDD Solutions-未检索到SettingID = 142176的数据 ENTER-在上下文内-使用SettingID = 142176进行查询-- Before SingleOrDefault -- - After SingleOrDefault -- - DBSetting为null

场景2:

SettingID = 138145的异常情况 ENTER-在上下文内-使用SettingID = 138145进行查询-- Before SingleOrDefault -- - After SingleOrDefault -- --指定的转换无效。

异常对象-MRDD Solutions-未检索到SettingID = 138145的数据 ENTER-在上下文内-使用SettingID = 138145进行查询-- Before SingleOrDefault -- - After SingleOrDefault --

场景3:

SettingID = 164638的异常情况 ENTER-在上下文内-使用SettingID = 164638进行查询-- Before SingleOrDefault -- --索引超出了数组界限。

异常对象-MRDD Solutions-未检索到SettingID = 164638的数据 ENTER-在上下文内-使用SettingID = 164638进行查询-- Before SingleOrDefault --


你的数据库中的SettingID列是什么类型? - Casey Wilkins
1
你的 CPT_Setting 类中的属性和数据库表列之间是否存在类型不匹配的问题?比如:某个列是文本类型,但对应的属性却是整型。 - Gert Arnold
我在每行代码后添加了更多的日志记录,并提出了一些场景,请检查这些。 - ravi
1
我知道VB.NET不区分大小写,但既然你的参数被列为“ByVal SettingId As Integer'”,那么LINQ查询不应该是:Where s.SettingId = **SettingId** _ 吗?此外,“CPT_Setting”类型可能拥有答案。那个类型上是否有需要可空而没有的属性?在使用LINQ对象将数据转储到没有可空类型的对象中时,我经常遇到这个转换问题。或者可能是返回空字符串的varchar类型被隐式转换为整数属性。 - atconway
你是否使用“Option Strict On”编译你的代码? - sloth
显示剩余4条评论
4个回答

4

我已经跟微软支持进行了跟进,我们启用了debugdiag追踪和分析dump文件,但是没有取得任何进展。

经过大量分析,我发现有3/4台服务器没有最新的框架更新,因此服务器管理员已经使用.Net Framework 4的可靠性更新1更新了这些机器,看起来问题已经解决了。没有进行任何代码更改。自更新以来已经过去两个星期,这个代码块中没有看到任何异常。

我浪费了一个月的时间。真该死。有时候问题并不在代码上。


1

不要使用 ToString(),而是要使用 Convert.ToString()

希望这能解决你的问题。


0

你应该检查一下

From s In context.CPT_Settings _
Where s.SettingId = settingId _
Select s

不会返回多个对象。也许它永远不应该这样,但这可能是问题所在。


SettingID 是主键,因此它将仅返回一个值。我也尝试过使用 .SingleOrDefault。错误似乎一直发生。 - ravi

0

使用Single而不是SingleOrDefault?

这就是我们最近在工作中解决类似情况的方法。


我也尝试了那个,但是没用。 - ravi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接