2011-03-31 31 views
43

He visto algunos ejemplos en los que decimal se usa en proyectos NHibernate para mapear columnas de números enteros en Oracle. En este momento estoy usando int y long en mi programa.¿Qué tipo de datos .NET es mejor para mapear el NÚMERO de tipo de datos de Oracle en NHibernate?

¿Cuáles son las ventajas de decimal sobre int/long? ¿Funciona mejor?

+0

¿Qué quiere decir con "¿Cuáles son las ventajas de decimal más int/tiempo? ¿Tiene que funcionan mejor?", Decimales no son números enteros como int/larga ... – Phill

+0

@Phill Sin embargo, un número decimal * * puede ** representar un número entero, y he visto 'decimal' utilizado en lugar de' int'/'long' en varios ejemplos. Solo estoy tratando de entender por qué. –

Respuesta

50

que he visto decimal usado en lugar de int/larga en varios ejemplos. Sólo estoy tratando de entender por qué

Eso es probablemente porque .NET decimal y Oracle NUMBERmaps a bit better de long y NUMBER y también le da más flexibilidad. Si en una etapa posterior agrega una escala en la columna Oracle, entonces no tendría que cambiar el tipo de datos si ya usó decimal.

decimal es ciertamente más lento que int y long ya que los dos últimos son compatibles con el hardware. Dicho esto, tienes que procesar una gran cantidad de datos para que haga una diferencia. Sigo pensando que debe usar long si eso es lo que está tratando y luego también debe dejar que las definiciones de columna de la tabla lo representen. NUMBER(18,0) para long y así sucesivamente.

La razón decimal mapas un poco mejor es que long es de 64 bits y decimal es (tipo de) 128 bits.

.NET

Tipo: decimal
intervalo aproximado: ± 1,0 × 10^-28 a ± 7,9 × 10^28
de precisión: 28-29 dígitos significativos

Tipo: largo
Rango: -9,223,372,036,854,77 5.808 a 9,223,372,036,854,775,807
Precisión: 18 (19 para ulong) dígitos significativos

Oracle

NUMBERdefaults a 38 dígitos significativos y la escala de 0 (entero).

Tipo: NÚMERO
Rango: + - 1 x 10^-130-9,99 ...9 x 10^125
de precisión: 38 dígitos significativos

Microsoft es consciente del problema y notes

Este tipo de datos es un alias para el NÚMERO (38) de tipo de datos, y está diseñado para que OracleDataReader devuelva System.Decimal u OracleNumber en su lugar de un valor entero. El uso del .NET tipo de datos de Framework puede causar un desbordamiento de .

Ahora que lo pienso de ella que realmente necesita BigInteger a ser capaz de representar el mismo número de dígitos significativos en cuanto a lo NUMBER por defecto. Nunca he visto a nadie hacer eso y supongo que es una necesidad muy rara. También BigInteger todavía no lo cortaría ya que NUMBER puede ser de infinito positivo y negativo.

+0

Aprende algo nuevo todos los días :) – Phill

+0

// Esto tiene mucho más sentido para mí. Muchas gracias Jonas por esta gran explicación ...! –

+0

En caso de apuro, siempre puede usar el mapa para 'Oracle.ManagedDataAccess.Types.OracleDecimal' como se insinúa en https://docs.oracle.com/cd/B28359_01/win.111/b28375/featTypes.htm - IIRC funciona con Number (38) y maneja +/- INF casos. – quetzalcoatl

30
[.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] 
+1

No sé de dónde sacaste esto, pero esto no es lo que sucede de facto. Por lo que veo, 'double' está mapeado a' DOUBLE PRECISION', 'int' siempre se mapea a' NUMBER (10,0) 'y' decimal' se puede mapear a cualquier 'NUMBER (x, y)' dependiendo de la configuración '.Precision (x) .Scale (y)'. Por cierto, cambiar el '.Precision' de' int' no cambia la asignación, sigue siendo 'NUMBER (10,0)'. Y además, esto no responde mi pregunta. –

+0

Uso 'Devart', leí la siguiente respuesta que describe los tipos de mapeo CSDL entre Oracle y .Net .http: //www.devart.com/forums/viewtopic.php? T = 15604 – Homam

+2

Pero pregunté por NHibernate. .. –

7
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  
Cuestiones relacionadas