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
First of all, your understanding of Precision
and Scale
is wrong. Precision
is always higher than Scale
. See this MSDN documentation for a better understanding, which states:
Precision is the number of digits in a number. Scale is the number of digits to the right of the decimal point in a number. For example, the number 123.45 has a precision of 5 and a scale of 2.
In your second example, i.e. Decimal(18,0)
, 0 is Scale
, not Precision
. Precision
is 18.
Secondly, your mapping should be this:
Map(Function(x) x.Balance).CustomSqlType("decimal").Precision(9).Scale(2);
If you set CustomSqlType("decimal")
after setting Precision
and Scale
, the settings done by you will be reset.
EDIT:
You are using double
in the declaration, where I think you should use decimal
. See this question to know why. double
is a floating type variable so it is mapped to a float
by default until you mention otherwise or until the Precision
is higher than 7. If you change the declaration of Balance
to decimal
, you can map the property like this without any problems:
Map(Function(x) x.Balance).Precision(9).Scale(2)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With