web-dev-qa-db-fra.com

Quel type de données .NET convient le mieux pour mapper le type de données NUMBER Oracle dans NHibernate?

J'ai vu quelques exemples dans lesquels decimal est utilisé dans des projets NHibernate pour le mappage à des colonnes de nombres entiers dans Oracle. Actuellement, j'utilise int et long dans mon programme.

Quels sont les avantages de decimal par rapport à int/long? Fonctionne-t-il mieux?

45
Ilya Kogan

J'ai vu décimal utilisé au lieu de int/long dans divers exemples. J'essaie juste de comprendre pourquoi

C'est probablement parce que .NET decimal et Oracle NUMBERmappe un peu mieux que long et NUMBER et cela vous donne également plus souplesse. Si, à un stade ultérieur, vous ajoutez un scale dans la colonne Oracle, vous n'aurez pas à modifier le type de données si vous avez déjà utilisé decimal.

decimal est certainement plus lent que int et long car les deux derniers sont pris en charge par le matériel. Cela dit, vous devez croquer une quantité importante de données pour que cela fasse une différence. Je pense toujours que vous devriez utiliser long si c'est ce à quoi vous avez affaire et que vous devriez également laisser les définitions des colonnes du tableau représenter cela. NUMBER(18,0) pour long et ainsi de suite.

La raison pour laquelle decimal mappe un peu mieux est que long est 64 bits et decimal est (en quelque sorte) 128 bits.

. NET

Type: décimal
Plage approximative: ± 1,0 × 10 ^ −28 à ± 7,9 × 10 ^ 28
Précision: 28-29 chiffres significatifs

Type: long
Fourchette: –9 223 372 036 854 775 808 à 9 223 372 036 854 775 807
Précision: 18 (19 pour ulong) chiffres significatifs

Oracle

NUMBERpar défaut à 38 chiffres significatifs et échelle 0 (entier).

Tapez: [~ # ~] numéro [~ # ~]
Plage: + - 1 x 10 ^ -130 à 9,99 ... 9 x 10 ^ 125
Précision: 38 chiffres significatifs

Microsoft est conscient du problème et notes

Ce type de données est un alias pour le type de données NUMBER (38) et est conçu pour que OracleDataReader renvoie un System.Decimal ou OracleNumber au lieu d'une valeur entière. L'utilisation du type de données .NET Framework peut provoquer un débordement.

À bien y penser, vous avez réellement besoin de BigInteger pour pouvoir représenter le même nombre de chiffres significatifs que ce que NUMBER est par défaut. Je n'ai jamais vu personne faire ça et je suppose que c'est un besoin très rare. De plus, BigInteger ne le couperait toujours pas puisque NUMBER peut être d'infini positif et négatif.

57
Jonas Elfström
[.NET: Int32] = [Oracle:NUMBER(2)..NUMBER(9)*] 
[.NET: Int64] = [Oracle:NUMBER(10)..NUMBER(18)*]
[.NET: Double] = [Oracle:NUMBER(x, 0)..NUMBER(x, 15)*]
[.NET: Double] = [Oracle: FLOAT]
[.NET: Decimal] = [Oracle:NUMBER]  
39
Homam
NUMBER(1,0)     => Boolean          
NUMBER(5,0)     => Int16/short.MaxValue == 32767    
NUMBER(10,0)    => Int32/int.MaxValue == 2,147,483,647    
NUMBER(19,0)    => Int64/long.MaxValue == 9,223,372,036,854,775,807    
12
Carl Prothman