哪种 .NET 数据类型最适合在 NHibernate 中映射 NUMBER Oracle 数据类型?
Posted
技术标签:
【中文标题】哪种 .NET 数据类型最适合在 NHibernate 中映射 NUMBER Oracle 数据类型?【英文标题】:Which .NET data type is best for mapping the NUMBER Oracle data type in NHibernate? 【发布时间】:2011-07-26 23:58:09 【问题描述】:我见过一些例子,其中decimal
在 NHibernate 项目中用于映射到 Oracle 中的整数列。现在我在我的程序中使用int
和long
。
decimal
相对于int
/long
有哪些优势?效果更好吗?
【问题讨论】:
“十进制相对于 int/long 有什么优势?性能更好吗?”是什么意思,小数不像 int/long 那样是整数... @Phill 然而,一个小数可以代表一个整数,而且我看到在各种例子中用decimal
代替int
/long
。我只是想了解原因。
【参考方案1】:
[.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]
【讨论】:
我不知道你是从哪里得到这个的,但事实并非如此。据我所见,double
映射到DOUBLE PRECISION
,int
始终映射到NUMBER(10,0)
,decimal
可以映射到任何NUMBER(x,y)
,具体取决于.Precision(x).Scale(y)
设置。顺便说一句,更改int
的.Precision
不会更改映射 - 它仍然是NUMBER(10,0)
。此外,这并不能回答我的问题。
我使用Devart
,我阅读了以下描述Oracle和.Net之间的CSDL映射类型的答案。devart.com/forums/viewtopic.php?t=15604
这取决于你锁定问题的方式:如果你想存储一个int32
(max = 2,147,483,647)
,你需要一个NUMBER(10,0)
。如果你想阅读NUMBER(10,0)
(max = 9,999,999,999)
,你需要long
。由于边界遵循完全不同的概念,因此无法绕过。你必须知道数据来自哪里,并且可能使用额外的数据库约束。【参考方案2】:
我在各种示例中看到使用十进制而不是 int/long。我只是想了解原因
这可能是因为 .NET decimal
和 Oracle NUMBER
maps a bit better 比 long
和 NUMBER
更灵活。如果您稍后在 Oracle 列中添加 scale,那么如果您已经使用了decimal
,则无需更改数据类型。
decimal
肯定比int
和long
慢,因为硬件支持后两者。也就是说,您必须处理大量数据才能发挥作用。我仍然认为你应该使用long
,如果那是你正在处理的,那么你也应该让表列定义代表它。 NUMBER(18,0)
为long
等等。
decimal
映射更好一点的原因是 long
是 64 位,decimal
是(有点)128 位。
.NET
类型:十进制 近似范围:±1.0 × 10^−28 至 ±7.9 × 10^28 精度:28-29 位有效数字
类型:long 范围:–9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 精度:18(ulong 为 19)有效数字
甲骨文
NUMBER
defaults 到 38 位有效数字和小数位数 0(整数)。
类型:NUMBER 范围:+- 1 x 10^-130 到 9.99...9 x 10^125 精度:38 位有效数字
Microsoft 已意识到该问题并notes
此数据类型是 NUMBER(38) 数据类型,设计 以便 OracleDataReader 返回一个 改为 System.Decimal 或 OracleNumber 的整数值。使用 .NET 框架数据类型可能导致 溢出。
想想看,您实际上需要BigInteger
才能表示与NUMBER
默认值相同的有效数字位数。我从未见过有人这样做,我想这是一个非常罕见的需求。同样BigInteger
仍然不会削减它,因为NUMBER
可以是正无穷大和负无穷大。
【讨论】:
每天学习新东西 :) //这对我来说更有意义。非常感谢乔纳斯的精彩解释......! 在紧要关头,您始终可以使用映射到Oracle.ManagedDataAccess.Types.OracleDecimal
,正如 docs.oracle.com/cd/B28359_01/win.111/b28375/featTypes.htm 中所暗示的那样 - IIRC 与 Number(38) 一起使用并处理 +/-INF 情况。【参考方案3】:
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
【讨论】:
以上是关于哪种 .NET 数据类型最适合在 NHibernate 中映射 NUMBER Oracle 数据类型?的主要内容,如果未能解决你的问题,请参考以下文章
哪种 HSQLDB 数据类型最适合 5000 个字符串:NTEXT、CLOB 或其他。?