首页 > 解决方案 > Oracle ManagedDataAccess GetDecimal 指定的强制转换无效

问题描述

我正在使用 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 reader, Int32 ordinal) 在 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(String providerManifestToken, DbProviderServices providerServices, Type[] columnTypes, Boolean[] nullableColumns) 在 System.Data.Entity.Core.Objects。内部的。System.Data.Entity.Core.Objects.ObjectQuery 处的 ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)1.<>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.ObjectQuery 1.<>c__DisplayClassb.<GetResults>b__9() at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func1 操作) 在 System.Data.Entity.Core.Objects.ObjectQuery 1.GetResults(Nullable1 forMergeOption) 在 System.Data.Entity.Core .Objects.ObjectQuery 1.CreateValue 1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0() at System.Lazy() 在 System.Lazy 1.LazyInitValue() at System.Lazy1.get_Value() 在 System.Data.Entity.Internal.LazyEnumerator 1.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](Expression 表达式) 在 System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[ TResult](Expression expression) at System.Linq.Queryable.First[TSource](IQueryable`1 source) at TransakcijskiCertifikatGOTS.Program.Main(String[] args) in C:\Users\sl0gas\Desktop\JiraRepo\Proizvodnja\TransportniCertifikatiGOTS \TransakcijskiCertifikatGOTS\TransakcijskiCertifikatGOTS\Program.cs:第 34 行

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

  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. 将默认转换从十进制更改为字符串,以便我可以手动转换为十进制或双精度,但提供程序抛出无效转换异常。

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

标签: c#oracleentity-frameworkentity-framework-6oracle-manageddataaccess

解决方案


我在函数调用和表格中遇到了这个问题。对于表格列,我将 .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 框架内可处理的大小并返回有效的十进制值。这对我来说已经有一段时间了。


推荐阅读