2010-02-26 8 views
8

Il mio campo di database (sql server 2005) è definito con valori numerici (15,2).Punti decimali che non arrotondano correttamente: si tratta di un errore LINQ to SQL?

Il LINQ 2 SQL struttura generata è

[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(); 
      } 
     } 
    } 

In debug di controllo il valore dell'entità per questa struttura = 23,6363,636363 millions (etc)

Poi scavalcare context.SubmitChanges()

Ho SQL Profiler in esecuzione e questa è la dichiarazione di aggiornamento.

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 

Come potete vedere @ p9 = 23,63, mi aspetto che sia 23,64.

Aggiornamento

La mia domanda è,

Se questo è un LINQ to SQL bug mi aspetto che sia un noto uno, dove avrei trovato questo fuori; c'è una lista di bug mantenuta da qualche parte?

Anche quale sarebbe il miglior lavoro intorno?

  • Sto indovinando cambiando il campo per 15,3 non sarebbe risolvere il bug, sarebbe solo spostarlo 1 decimale.
  • L'override di OnMy_Property_NameChanged() funzionerebbe per questa proprietà, ma ne ho molti.

Update 2

questo non ha funzionato neanche, va in questo pezzo di codice prima SubmitChanges e sembra funzionare, ma l'aggiornamento di SQL generato ha ancora il valore troncato, non questa aggiornato arrotondato valore.

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

La correzione che ho al momento è solo per aggiornare direttamente il valore dell'entità.

risposta

1

MSDN dice:

decimali e denaro Tipi Il predefinite di precisione di tipo DECIMAL di SQL Server (18 cifre decimali a sinistra e destra del punto decimale) è molto inferiore alla precisione di CLR Tipo decimale a cui è associato con il valore predefinito . Ciò può comportare una perdita di precisione quando si salvano i dati nel database . Tuttavia, è possibile che il valore opposto si verifichi se il tipo di SQL Server DECIMAL è configurato con un numero maggiore di 29 cifre di precisione. Quando un tipo DECIMAL del server SQL è stato configurato con una precisione maggiore rispetto al sistema CLR.Decimale, precisione perdita può verificarsi durante il recupero dei dati dal database.

È possibile gestirlo ignorando OnMy_Property_NameChanged() e arrotondandolo. Assicurati di specificare la modalità di arrotondamento corretta (da pari o da zero).

+0

se aggiorno il database direttamente con 23.63636363636363 allora diventa 23.64 .... che è ok. se ho scavalcato la proprietà, allora aggiusterò questa proprietà ma è un grosso db con un sacco di 15,2 campi definiti ... Non voglio davvero farlo per tutti loro. Penserei che se questo è un bug di Linq 2 Sql sarebbe stato trovato prima ?? (grazie per la risposta) –

+0

Suggerisco di scavare negli interni di linq2sql usando il riflettore se ne avete fiducia. Ovviamente è qualcosa sul generatore di query. –

0

sembra il bug di LINQ. è necessario modificare DBType da Decimal(15,2) a Decimal(15,3). Questa è l'incremento di 1 precisione in più rispetto alla precisione della colonna nel database.

+0

Tuttavia, tale colonna verrà creata come (15,3) nel caso in cui si utilizzi la creazione automatica del database. –

1

Sembra a me come se il link di SQL è troncando il valore a 2 cifre decimali invece di arrotondamento esso.