FluentNHibernate 映射;无法使用比例/精度映射双精度或小数

发布于 2024-10-15 14:59:26 字数 4380 浏览 3 评论 0原文

我第一次使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清欢 2024-10-22 14:59:26

首先,您对 PrecisionScale 的理解是错误的。 精度始终高于比例。请参阅此 MSDN 文档以获得更好的理解,其中指出:

精度是指a中的位数
数字。刻度是位数
小数点右边
数字。例如,数字 123.45
精度为 5,小数位数为 2。

在第二个示例中,即 Decimal(18,0),0 是 Scale,而不是 Precision >。 Precision 是 18。

其次,您的映射应该是这样的:

Map(Function(x) x.Balance).CustomSqlType("decimal").Precision(9).Scale(2);

如果您在设置 Precision 和 <之后设置 CustomSqlType("decimal") code>Scale,您所做的设置将被重置。

编辑:
您在声明中使用了 double ,我认为您应该使用decimal 。请参阅此问题了解原因。 double 是一个浮点类型变量,因此默认情况下它会映射到 float,除非您另有说明或直到 Precision 高于 7。如果您将 Balance 的声明更改为 decimal,您可以像这样映射属性,没有任何问题:

Map(Function(x) x.Balance).Precision(9).Scale(2)

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文