本文介绍了EF + ODP.NET + CLOB =值不能为空 - 参数名称:byteArray?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的项目最近更新到了较新的Oracle.ManagedDataAccess DLL(v 4.121.2.0),并且间歇性地出现了此错误。我们已经修复了几次,而不知道我们做了什么来修复它。



我相当确定它是由CLOB字段映射到Entity Framework中的字符串引起的,然后在LINQ语句中被选中,而不是仅限于一组有限的属性。



错误:

 值不能为空。 
参数名称:byteArray

堆栈跟踪:


$ b在System.BitConverter.ToString(Byte [] value,Int32 startIndex,Int32长度)$ b $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $
在OracleInternal.ServiceObjects.OracleDataReaderImpl.CollectTempLOBsToBeFreed(Int32 rowNumber)
在Oracle.ManagedDataAccess.Client.OracleDataReader.ProcessAnyTempLOBs(Int32 rowNumber)
在Oracle.ManagedDataAccess.Client.OracleDataReader.Read()
在System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.StoreRead()

可疑实体属性:

 映射到Oracle CLOB列'
<列(LARGEFIELD )>
公共财产LargeField As String

但我相信这是正确的映射方式每个Oracle矩阵的字段:





生成的SQL语句没有任何明显的错误:

  SELECT 
...
Extent1。LARGEFIELD作为LARGEFIELD,
...
FROM ...Extent1
WHERE ...

我也试过了每个Ozkan的建议流畅的代码,但似乎并不影响我的情况。

  modelBuilder.Entity(Of [CLASS])( ).Property(
函数(x)x.LargeField
).IsOptional()

疑难解答更新:



经过广泛的测试,我们确信这实际上是一个错误,而不是配置问题。它似乎是CLOB的内容,导致问题在一个非常具体的情况下。我已经在上交叉发布,希望更多信息。

解决方案

我们在某些计算机上也有这个问题,我们正在运行最新的Oracle.ManagedDataAccess.dll 4.121.2.20150926 ODAC RELEASE 4)。



我们找到了解决问题的方案,我只想分享。



 使用连接作为新的OracleConnection(yourConnectionString)
Dim命令作为新的OracleCommand(yourQuery,连接)
connection.Open()

使用阅读器作为OracleDataReader = command.ExecuteReader()
Dim clobField As String = CStr(reader.Item CLOB_FIELD))
结束使用

connection.Close()
结束使用

这里的解决方案使其在所有计算机上工作

 使用连接作为新的OracleConnection(yourConnectionString)
Dim命令作为新的OracleCommand(yourQuery,连接)
connection.Open()

使用阅读器作为OracleDataReader = command.ExecuteReader()
Dim clobField As String = reader.GetOracleClob(0).Value
End Using

connection.Close()
结束使用


Our project recently updated to the newer Oracle.ManagedDataAccess DLL's (v 4.121.2.0) and this error has been cropping up intermittently. We've fixed it a few times without really knowing what we did to fix it.

I'm fairly certain it's caused by CLOB fields being mapped to strings in Entity Framework, and then being selected in LINQ statements that pull entire entities instead of just a limited set of properties.

Error:

Value cannot be null.
Parameter name: byteArray

Stack Trace:

   at System.BitConverter.ToString(Byte[] value, Int32 startIndex, Int32 length)
   at OracleInternal.TTC.TTCLob.GetLobIdString(Byte[] lobLocator)
   at OracleInternal.ServiceObjects.OracleDataReaderImpl.CollectTempLOBsToBeFreed(Int32 rowNumber)
   at Oracle.ManagedDataAccess.Client.OracleDataReader.ProcessAnyTempLOBs(Int32 rowNumber)
   at Oracle.ManagedDataAccess.Client.OracleDataReader.Read()
   at System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.StoreRead()

Suspect Entity Properties:

'Mapped to Oracle CLOB Column'
<Column("LARGEFIELD")>
Public Property LargeField As String

But I'm confident this is the proper way to map the fields per Oracle's matrix:

ODP.NET Types Overview

There is nothing obviously wrong with the generated SQL statement either:

SELECT
...
"Extent1"."LARGEFIELD" AS "LARGEFIELD",
...
FROM ... "Extent1"
WHERE ...

I have also tried this Fluent code per Ozkan's suggestion, but it does not seem to affect my case.

modelBuilder.Entity(Of [CLASS])().Property(
    Function(x) x.LargeField
).IsOptional()

Troubleshooting Update:

After extensive testing, we are quite certain this is actually a bug, not a configuration problem. It appears to be the contents of the CLOB that cause the problem under a very specific set of circumstances. I've cross-posted this on the Oracle Forums, hoping for more information.

解决方案

We have this problem as well on some computers, and we are running the latest Oracle.ManagedDataAccess.dll (4.121.2.20150926 ODAC RELEASE 4).

We found a solution to our problem, and I just wanted to share.

This was our problem that occurred some computers.

Using connection As New OracleConnection(yourConnectionString)
    Dim command As New OracleCommand(yourQuery, connection)
    connection.Open()

    Using reader As OracleDataReader = command.ExecuteReader()
        Dim clobField As String = CStr(reader.Item("CLOB_FIELD"))
    End Using

    connection.Close()
End Using

And here's the solution that made it work on all computers.

Using connection As New OracleConnection(yourConnectionString)
    Dim command As New OracleCommand(yourQuery, connection)
    connection.Open()

    Using reader As OracleDataReader = command.ExecuteReader()
        Dim clobField As String = reader.GetOracleClob(0).Value
    End Using

    connection.Close()
End Using

这篇关于EF + ODP.NET + CLOB =值不能为空 - 参数名称:byteArray?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 13:13