Отображение FluentNHibernate; Невозможно отобразить двойное или десятичное с масштабом / точностью

Я впервые работаю с FluentNHibernate, пытаясь сопоставить классы с базой данных SQL Express. В целом это работает, но я не могу сопоставить типы свойств Double или Decimal с конкретным масштабом / точностью. Ниже показан результат для одного свойства, которое я неоднократно тестировал с помощью SchemaUpdate.Execute. Ни в коем случае мне не удавалось заставить его работать.

Было бы действительно полезно услышать некоторые объяснения сопоставлений, которые не работают так, как я ожидал (2-8)?

// Ok mappings:

1) Десятичный: Карта (Функция (x) x Баланс) >> Десятичный (19, 5)

// Mappings "errors":

2) Double: Map (Function (x) x.Balance) .CustomSqlType ("decimal") >> Decimal (18,0) - почему по умолчанию используется точность 0 отображение здесь?

3) Double: карта (функция (x) x.Balance) >> Float, But; при запуске SchemaValidator после: HibernateException: неправильный тип столбца в FnhDb.dbo.Account для столбца Balance. Найдено: float, Ожидаемая ДВОЙНАЯ ТОЧНОСТЬ

4) Десятичное число: карта (функция (x) xBalance) .Scale (9) .Precision (2) >> SqlException: шкала (9) для столбца «Баланс» должна находиться в диапазоне от 0 до 2.

5,6) Десятичный или двойной: карта (функция (x) xBalance) .Scale (9) .Precision (2) .CustomSqlType ("numeric") >> числовой (18,0)

7,8) Decimal или Double: Map (Function (x) xBalance) .Scale (9) .Precision (2) .CustomSqlType ("decimal") >> Десятичный (18,0)


РЕДАКТИРОВАТЬ: Я включаю здесь код и hbm.xml (экспорт) для случая (4):

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>

РЕДАКТИРОВАТЬ2:

Кстати, это не проблема VB. У меня такая же проблема в проекте C #. Может быть, конфигурация MsSql2008 несовместима с Sql Express 2008 R2?


РЕДАКТИРОВАТЬ3:

Option Strict On

Импорт System.Collections.Generic Imports System.Text Система импорта

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

person bretddog    schedule 31.01.2011    source источник


Ответы (1)


Во-первых, ваше понимание Precision и Scale неверно. Precision всегда выше, чем Scale. Для лучшего понимания см. эту документацию MSDN, в которой говорится:

Точность - это количество цифр в числе. Масштаб - это количество цифр справа от десятичной точки в числе. Например, число 123,45 имеет точность 5 и масштаб 2.

Во втором примере, т.е. Decimal(18,0), 0 - это Scale, а не Precision. Precision - 18 лет.

Во-вторых, ваше отображение должно быть таким:

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

Если вы установите CustomSqlType("decimal") после настройки Precision и Scale, сделанные вами настройки будут сброшены.

РЕДАКТИРОВАТЬ:
Вы используете double в объявлении, где, я думаю, вам следует использовать decimal. См. этот вопрос, чтобы узнать почему. double - это переменная плавающего типа, поэтому по умолчанию она сопоставляется с float, пока вы не укажете иное или пока Precision не станет больше 7. Если вы измените объявление Balance на decimal, вы можете без проблем сопоставить это свойство:

Map(Function(x) x.Balance).Precision(9).Scale(2)
person Yogesh    schedule 31.01.2011
comment
Ай .. Спасибо! Я проверил эту точную вещь (Def. Of precision / scale), но тогда, должно быть, прочитал ее неправильно ... Ну, это оставляет меня, думаю, только с одним вопросом: почему я не могу сопоставить double с Decimal / числовой? Как он всегда будет создавать столбец (18,0)? - person bretddog; 31.01.2011
comment
Это зависит от того, как вы объявили свойство Balance в своем объекте. Можете ли вы опубликовать объявление объекта POCO? - person Yogesh; 31.01.2011
comment
Хорошо, я добавил весь класс выше. А теперь сопоставление, как вы сказали: Map (Function (x) x.Balance) .CustomSqlType (decimal) .Precision (9) .Scale (2) - person bretddog; 31.01.2011
comment
Хм. Да, я читал много дискуссий о двойных / десятичных дробях. И в этом примере свойство decimal может быть подходящим, но разве не должно быть вообще возможно сопоставить double с указанной точностью / масштабом десятичного / числового? Считается ли это запретом для ORM или базы данных делать это преобразование? - person bretddog; 31.01.2011
comment
На самом деле это зависит от вашего объявления объекта, в какое поле база данных / ORM сопоставляет ваше свойство. Сначала вам нужно правильно объявить его, потому что именно так работает Fluent NHibernate. - person Yogesh; 31.01.2011
comment
Понятно. Хорошо, теперь я думаю, что для меня все это имеет смысл. Ваше здоровье! :) - person bretddog; 31.01.2011