【问题标题】:Oracle ManagedDataAccess GetDecimal specified cast is not validOracle ManagedDataAccess GetDecimal 指定的强制转换无效
【发布时间】:2020-02-02 07:49:56
【问题描述】:

我正在使用 EF6 Oracle.ManagedDataAccess v18.3.0,数据库优先概念 (edmx)。问题是 Oracle 表存储的 Number 具有更高的精度(38 位),即 oracle Number 映射到的默认 Decimal C# 数据类型。十进制的最大精度为 28-29 位。因为那个 OracleManagedDataAccess 提供者在下面抛出异常:

在 Oracle.ManagedDataAccess.Client.OracleDataReader.GetDecimal(Int32 i) 在 System.Data.Entity.Core.Objects.Internal.ShapedBufferedDataRecord.ReadDecimal(DbDataReader 阅读器,Int32 序数) 在 System.Data.Entity.Core.Objects.Internal.ShapedBufferedDataRecord.Initialize(DbDataReader 阅读器,DbSpatialDataReader spatialDataReader,Type[] columnTypes,Boolean[] nullableColumns) 在 System.Data.Entity.Core.Objects.Internal.ShapedBufferedDataRecord.Initialize(字符串 providerManifestToken,DbProviderServices providerServices,DbDataReader 阅读器,Type[] columnTypes,Boolean[] nullableColumns) 在 System.Data.Entity.Core.Objects.Internal.BufferedDataReader.Initialize(字符串 providerManifestToken,DbProviderServices providerServices,Type[] columnTypes,Boolean[] nullableColumns) 在 System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext 上下文,ObjectParameterCollection 参数值) 在 System.Data.Entity.Core.Objects.ObjectQuery1.<>c__DisplayClassb.<GetResults>b__a() at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) 在 System.Data.Entity.Core.Objects.ObjectQuery1.<>c__DisplayClassb.<GetResults>b__9() at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func1 操作) 在 System.Data.Entity.Core.Objects.ObjectQuery1.GetResults(Nullable1 forMergeOption) 在 System.Data.Entity.Core.Objects.ObjectQuery1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0() at System.Lazy1.CreateValue() 在 System.Lazy1.LazyInitValue() at System.Lazy1.get_Value() 在 System.Data.Entity.Internal.LazyEnumerator1.MoveNext() at System.Linq.Enumerable.First[TSource](IEnumerable1 来源) 在 System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.b__0[TResult](IEnumerable1 sequence) at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable1 查询,表达式 queryRoot) 在 System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](表达式表达式) 在 System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](表达式表达式) 在 System.Linq.Queryable.First[TSource](IQueryable`1 源) 在 C:\Users\sl0gas\Desktop\JiraRepo\Proizvodnja\TransportniCertifikatiGOTS\TransakcijskiCertifikatGOTS\TransakcijskiCertifikatGOTS\TransakcijskiCertifikatGOTS\Program.cs:line 34 中的 TransakcijskiCertifikatGOTS.Program.Main(String[] args) 处

是否有任何已知的解决方法可以解决此问题?到目前为止,我已经尝试过:

  1. 将导致 edmx 文件中问题的特定成员的精度设置为 28,
  2. 将 App.config 更改为以下配置并尝试不同的选项

      <edmMappings>
    <edmNumberMapping>
      <add NETType="bool" MinPrecision="1" MaxPrecision="1" DBType="Number" />
      <add NETType="int16" MinPrecision="2" MaxPrecision="5" DBType="Number" />
      <add NETType="int32" MinPrecision="6" MaxPrecision="10" DBType="Number" />
      <add NETType="int64" MinPrecision="11" MaxPrecision="19" DBType="Number" />
      <add NETType="Decimal" MinPrecision="20" MaxPrecision="28" DBType="Number" />
      <add NETType="String" MinPrecision="29" MaxPrecision="38" DBType="Number" />
    </edmNumberMapping>
    

  3. 将默认转换从 Decimal 更改为字符串,以便我可以手动转换为 Decimal 或 double,但提供程序抛出无效转换异常。

我正在使用 LINQ 语法来查询数据库!

【问题讨论】:

    标签: c# oracle entity-framework entity-framework-6 oracle-manageddataaccess


    【解决方案1】:

    我在函数调用和表格中遇到了这个问题。对于表格列,我将 .NET 类型更改为 double 并处理了转换 - 到目前为止,我还没有遇到任何精度问题。

    我的函数调用解决方法如下:

    var command = "some_oracle_function(:first_parameter)";
    
    var xx = context.Database.SqlQuery<string>(command, firstParameter).SingleOrDefault();
    var oracleDecimal = new OracleDecimal(xx);
    return oracleDecimal.IsNull ? 0 : OracleDecimal.SetPrecision(oracleDecimal, 28).Value
    

    我将响应强制为字符串并生成一个新的 OracleDecimal - 这允许大的溢出十进制数 - 然后我将其转换为 .NET 框架内可处理的大小并返回有效的十进制值。这对我来说已经有一段时间没有问题了。

    【讨论】:

    • 问题是我正在使用 Linq 查询从数据库中获取数据。正如我所见,您以字符串格式使用 SQL,然后将其传递给 ManagedProvider。当然我可以改用这种方法,但 Linq 有一些我在这种情况下需要的优势。
    • 尝试在 .NET 中使用 double 作为列类型
    • 如果我这样做,那么它会抛出这种错误“错误 2019:指定的成员映射无效。成员的类型 Edm.Double[Nullable=True,DefaultValue=]...”在类型“...”中与 OracleEFProcider.number [Nullable=True,DefaultValue=,Precision=38,Scale=0] 不兼容
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 2014-07-30
    • 2012-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多