FluentNHibernate 映射;无法使用比例/精度映射双精度或小数
我第一次使用 FluentNHibernate,尝试将类映射到 SQL Express 数据库。一般来说,它可以工作,但我无法将双精度或小数属性类型映射到特定的比例/精度。下面显示了我使用 SchemaUpdate.Execute 反复测试的单个属性的结果。在任何情况下我都无法让它发挥作用。
听到一些对未按我预期工作的映射的解释(2-8)真的很有帮助吗?
// Ok mappings:
1) Decimal: Map(Function(x) x.Balance) >> Decimal(19, 5)
// Mappings "errors":
2) Double: Map (Function(x) x.Balance).CustomSqlType("decimal") >> Decimal(18,0) - 为什么这里默认映射为 0 精度?
3) Double: Map(Function(x) x.Balance) >> Float , 但;当运行SchemaValidator时: HibernateException:FnhDb.dbo.Account 中“余额”列的列类型错误。发现:浮点数,预期双精度
4) 小数:Map(Function(x) x.Balance).Scale(9).Precision(2) >> SqlException:“余额”列的小数位数 (9) 必须在 0 到 2 的范围内。
5,6) Decimal 或 Double:Map(Function(x) x .Balance).Scale(9).Precision(2).CustomSqlType("numeric") >> numeric(18,0)
7,8) 十进制或双精度: Map(Function(x) x.Balance).Scale(9).Precision(2).CustomSqlType("decimal") >> Decimal(18,0)
编辑: 我在此处包含案例 (4) 的代码和 hbm.xml(导出):
Public Class AccountMap
Inherits ClassMap(Of Account)
Public Sub New()
MyBase.New()
Id(Function(x) x.Id).GeneratedBy.Identity()
Map(Function(x) x.Balance).Scale(9).Precision(2)
Map(Function(x) x.Deposits)
Map(Function(x) x.WithDrawals)
End Sub
End Class
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="false">
<class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="RoboTrader.Account, RoboTrader, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Account`">
<id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Id" />
<generator class="identity" />
</id>
<property name="Balance" type="System.Decimal, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Balance" precision="2" scale="9" />
</property>
<property name="Deposits" type="System.Nullable`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Deposits" />
</property>
<property name="WithDrawals" type="System.Nullable`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="WithDrawals" />
</property>
</class>
</hibernate-mapping>
EDIT2:
顺便说一句,这不是 VB 问题。我在 C# 项目中遇到了完全相同的问题。难道是MsSql2008配置与Sql Express 2008 R2不兼容?
EDIT3:
Option Strict On
导入 System.Collections.Generic 导入系统.文本 进口系统
Public Class Account
Public Sub New()
MyBase.New()
End Sub
Private _Id As Integer
Private _Balance As Double
Private _Deposits As Integer
Private _WithDrawals As Integer
Public Overridable Property Id() As Integer
Get
Return _Id
End Get
Set(ByVal value As Integer)
_Id = value
End Set
End Property
Public Overridable Property Balance() As Double
Get
Return _Balance
End Get
Set(ByVal value As Double)
_Balance = value
End Set
End Property
Public Overridable Property Deposits() As Integer
Get
Return _Deposits
End Get
Set(ByVal value As Integer)
_Deposits = value
End Set
End Property
Public Overridable Property WithDrawals() As Integer
Get
Return _WithDrawals
End Get
Set(ByVal value As Integer)
_WithDrawals = value
End Set
End Property
End Class
I'm working first time with FluentNHibernate, trying to map classes to SQL Express database. In general it works, but I'm unable to map Double or Decimal property types to specific scale/precision. Below shows result for a single property that I tested over and over with SchemaUpdate.Execute. In no case was I able to get it to work.
Would be really helpful to hear some explanation to the mappings that does not work as I expect (2-8)?
// Ok mappings:
1) Decimal: Map(Function(x) x.Balance) >> Decimal(19, 5)
// Mappings "errors":
2) Double: Map(Function(x) x.Balance).CustomSqlType("decimal") >> Decimal(18,0)
- Why 0 precision is the default mapping here?
3) Double: Map(Function(x) x.Balance) >> Float ,
But; when running SchemaValidator after:
HibernateException: Wrong column type in FnhDb.dbo.Account for column Balance. Found: float, Expected DOUBLE PRECISION
4) Decimal: Map(Function(x) x.Balance).Scale(9).Precision(2) >>
SqlException: The scale (9) for column 'Balance' must be within the range 0 to 2.
5,6) Decimal or Double: Map(Function(x) x.Balance).Scale(9).Precision(2).CustomSqlType("numeric") >> numeric(18,0)
7,8) Decimal or Double: Map(Function(x) x.Balance).Scale(9).Precision(2).CustomSqlType("decimal") >> Decimal(18,0)
EDIT:
I include code and hbm.xml (export) for case (4) here:
Public Class AccountMap
Inherits ClassMap(Of Account)
Public Sub New()
MyBase.New()
Id(Function(x) x.Id).GeneratedBy.Identity()
Map(Function(x) x.Balance).Scale(9).Precision(2)
Map(Function(x) x.Deposits)
Map(Function(x) x.WithDrawals)
End Sub
End Class
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="false">
<class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="RoboTrader.Account, RoboTrader, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Account`">
<id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Id" />
<generator class="identity" />
</id>
<property name="Balance" type="System.Decimal, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Balance" precision="2" scale="9" />
</property>
<property name="Deposits" type="System.Nullable`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Deposits" />
</property>
<property name="WithDrawals" type="System.Nullable`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="WithDrawals" />
</property>
</class>
</hibernate-mapping>
EDIT2:
Btw, this is not a VB issue. I have the exact same problem in a C# project. Can it be the MsSql2008 configuration that is not compatible with Sql Express 2008 R2?
EDIT3:
Option Strict On
Imports System.Collections.Generic
Imports System.Text
Imports System
Public Class Account
Public Sub New()
MyBase.New()
End Sub
Private _Id As Integer
Private _Balance As Double
Private _Deposits As Integer
Private _WithDrawals As Integer
Public Overridable Property Id() As Integer
Get
Return _Id
End Get
Set(ByVal value As Integer)
_Id = value
End Set
End Property
Public Overridable Property Balance() As Double
Get
Return _Balance
End Get
Set(ByVal value As Double)
_Balance = value
End Set
End Property
Public Overridable Property Deposits() As Integer
Get
Return _Deposits
End Get
Set(ByVal value As Integer)
_Deposits = value
End Set
End Property
Public Overridable Property WithDrawals() As Integer
Get
Return _WithDrawals
End Get
Set(ByVal value As Integer)
_WithDrawals = value
End Set
End Property
End Class
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,您对
Precision
和Scale
的理解是错误的。精度
始终高于比例
。请参阅此 MSDN 文档以获得更好的理解,其中指出:在第二个示例中,即
Decimal(18,0)
,0 是Scale
,而不是Precision
>。Precision
是 18。其次,您的映射应该是这样的:
如果您在设置
Precision
和 <之后设置CustomSqlType("decimal")
code>Scale,您所做的设置将被重置。编辑:
您在声明中使用了 double ,我认为您应该使用decimal 。请参阅此问题了解原因。
double
是一个浮点类型变量,因此默认情况下它会映射到float
,除非您另有说明或直到Precision
高于 7。如果您将Balance
的声明更改为decimal
,您可以像这样映射属性,没有任何问题:First of all, your understanding of
Precision
andScale
is wrong.Precision
is always higher thanScale
. See this MSDN documentation for a better understanding, which states:In your second example, i.e.
Decimal(18,0)
, 0 isScale
, notPrecision
.Precision
is 18.Secondly, your mapping should be this:
If you set
CustomSqlType("decimal")
after settingPrecision
andScale
, the settings done by you will be reset.EDIT:
You are using
double
in the declaration, where I think you should usedecimal
. See this question to know why.double
is a floating type variable so it is mapped to afloat
by default until you mention otherwise or until thePrecision
is higher than 7. If you change the declaration ofBalance
todecimal
, you can map the property like this without any problems: