Десятичные знаки неправильно округляются - это ошибка LINQ to SQL? - PullRequest
8 голосов
/ 26 февраля 2010

Поле моей базы данных (sql server 2005) определено с числовым значением (15,2).

Сгенерированное SQL LINQ 2 свойство

    [Column(Storage="_My_Property_Name", DbType="Decimal(15,2)", UpdateCheck=UpdateCheck.Never)]
    public System.Nullable<decimal> My_Property_Name
    {
        get
        {
            return this._My_Property_Name;
        }
        set
        {
            if ((this._My_Property_Name != value))
            {
                this.OnMy_Property_NameChanging(value);
                this.SendPropertyChanging();
                this._My_Property_Name = value;
                this.SendPropertyChanged("My_Property_Name");
                this.OnMy_Property_NameChanged();
            }
        }
    }

В отладке я проверяю значение сущности для этого свойства = 23.6363636363 (и т. Д.)

Затем я перехожу через context.SubmitChanges ()

У меня запущен SQL Profiler, и это оператор обновления.

exec sp_executesql N'
UPDATE [Staging].[My_Table_Name]
    SET [LAST_UPDATE_DATE] = @p2, [Field1] = @p3, [Field2] = @p4, [Field3] = @p5, [Field4] = @p6, [Field5] = @p7, [Field6] = @p8, [Field7] = @p9
WHERE ([Id] = @p0) AND ([RecordVersion] = @p1)

SELECT [t1].[RecordVersion] FROM [Staging].[My_Table_Name] AS [t1]
WHERE ((@@ROWCOUNT) > 0) AND ([t1].[Id] = @p10)',N'@p0 int,@p1 timestamp,@p2 datetime,@p3 decimal(21,8),@p4 decimal(21,8),@p5 decimal(21,8),@p6 decimal(21,8), @p7 decimal(21,8),@p8 decimal(21,8),@p9 decimal(15,2),@p10 int',@p0=2935,@p1=0x0000000000323018,@p2='2010-02-26 16:49:21:690', @p3=99.99992307,@p4=99.99992307,@p5=99.99992307,@p6=99.99992307,@p7=99.99992307,@p8=99.99992307,
@p9=23.63,@p10=2935

Как видите, @ p9 = 23,63, я ожидаю, что оно будет 23,64.

Обновление

Мой вопрос,

Если это ошибка LINQ to SQL, я ожидаю, что она будет известной, где я могу это выяснить; есть ли где-нибудь поддерживаемый список ошибок?

Также Как лучше всего обойтись?

  • Полагаю, что изменение поля на 15,3 не исправит ошибку, а просто сместит ее на 1 десятичное место.
  • Переопределение OnMy_Property_NameChanged () будет работать для этого свойства, но у меня их много.

Обновление 2

это тоже не сработало, оно входит в этот кусок кода перед submitchanges и кажется работающим, но сгенерированное обновление sql все еще имеет усеченное значение, а не это обновленное округленное значение.

partial void OnMy_Property_Name_ChangingChanging(decimal? value)
{
    if (!value.HasValue)
    {
        return;
    }
    value = 
        Math.Round(value.Value, 2, MidpointRounding.AwayFromZero);
}

Исправление, которое у меня есть на данный момент, - просто обновить значение сущности напрямую.

Ответы [ 3 ]

1 голос
/ 27 февраля 2010

Мне кажется, что ссылка на SQL усекает значение до 2 десятичных знаков вместо округления .

1 голос
/ 26 февраля 2010

MSDN говорит:

Десятичный и денежный типы По умолчанию точность типа SQL Server DECIMAL (18 десятичных цифр слева и право на десятичную точку) много меньше, чем точность CLR Тип десятичного числа, с которым он соединен дефолт. Это может привести к точности потеря при сохранении данных в база данных. Однако как раз наоборот может произойти, если SQL Server DECIMAL тип настроен с более чем 29 цифр точности. Когда SQL Тип DECIMAL сервера был настроен с большей точностью чем CLR System. десятичный, точность потеря может возникнуть при получении данных из базы данных.

Вы можете справиться с этим путем переопределения OnMy_Property_NameChanged() и округления его там. Убедитесь, что вы указали правильный режим округления (до четного или с нуля).

0 голосов
/ 26 февраля 2010

похоже ошибка LINQ. вам нужно изменить DBType с Decimal(15,2) на Decimal(15,3). Это на одну единицу больше точности, чем точность столбца в базе данных.

...