Oracle ManagedDataAccess GetDecimal указанное приведение недействительно - PullRequest
0 голосов
/ 02 февраля 2020

Я использую EF6 Oracle .ManagedDataAccess v18.3.0, первая концепция базы данных (edmx). Проблема состоит в том, что в таблице Oracle хранится число с более высокой точностью (38 цифр), чем тип данных по умолчанию Десятичное число C#, которому сопоставляется число oracle. Десятичная дробь имеет точность не более 28-29 цифр. Из-за этого провайдер OracleManagedDataAccess выбрасывает исключение ниже:

в Oracle .ManagedDataAccess.Client.OracleDataReader.GetDecimal (Int32 i) в System.Data.Entity.Core.Objects.Internal.ShapedBufferedDadecimal. (Читатель DbDataReader, порядковый номер Int32) в System.Data.Entity.Core.Objects.Internal.ShapedBufferedDataRecord.Initialize (читатель DbDataReader, DbSpatialDataReader пространственныйDataReader, Type [] columnTypes, Boolean [] nullableCores.ject.ity.ity.ity.itybject.itybject.itybject.ityb.jectb.jectb.jectb.jectb.jectb.ject.ity) в System. .Internal.ShapedBufferedDataRecord.Initialize (String providerManifestToken, DbProviderServices providerServices, DbDataReader читатель, Тип [] columnTypes, Boolean [] nullableColumns) при System.Data.Entity.Core.Objects.Internal.BufferedDataReader.Initialize (String providerManifestToken, DbProviderServices providerServices, Тип [] columnTypes, Boolean [] nullableColumns) в System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute [TResultType] (контекст ObjectContext, ObjectParameterCo параметр выбора (значения) в System.Data.Entity.Core.Objects.ObjectQuery 1.<>c__DisplayClassb.<GetResults>b__a() at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func 1 fun c, IDbExecutionStrategy executeStrategy, логическое значение startLocalTransaction, логическое значение releaseConnectionOnSuccess) в System.Data.Entity.Core.Objects.Object. ) в System.Data.Entity.Core.Objects.ObjectQuery 1.GetResults(Nullable 1 forMergeOption) в System.Data.Entity.Core.Objects.ObjectQuery 1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0() at System.Lazy 1.CreateValue () в System.Lazy 1.LazyInitValue() at System.Lazy 1.get_Value ( ) в System.Data.Entity.Internal.LazyEnumerator 1.MoveNext() at System.Linq.Enumerable.First[TSource](IEnumerable 1 source) в System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.b__0 [TResult] (запрос IEnumerable 1 sequence) at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable 1, запрос выражения Root) в 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) в TransakcijskiCertifikatGOTS.Program.Main (String [] args) в C: \ Users \ sl0gas \ Desktop \ JiraRep o \ Proizvodnja \ TransportniCertifikatiGOTS \ TransakcijskiCertifikatGOTS \ TransakcijskiCertifikatGOTS \ Program.cs: строка 34

Есть ли какие-либо известные обходные пути для решения этой проблемы? До сих пор я пробовал это:

  1. Установка точности для специфицируемого c члена, который вызывает проблему в файле 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 для запроса к базе данных!

1 Ответ

0 голосов
/ 05 февраля 2020

У меня была эта проблема с вызовом функции, а также с таблицей. Для столбца таблицы я изменил тип. NET на удвоение и обработал преобразование - до сих пор у меня не было проблем с точностью.

Мой обходной путь для вызова функции заключается в следующем:

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 и возвращают действительное десятичное значение. Это работало без проблем для меня в течение некоторого времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...