EF6 wydaje się być niekonsekwentny w sposobie obsługi zaokrąglania podczas mnożenia i dodawania kolumn całkowitych z wartościami dziesiętnymi.Entity Framework zaokrąglanie dziesiętne niespójne w projekcji
// CREATE TABLE MyTable (MyIntValue INT NOT NULL)
// INSERT INTO MyTable (MyIntValue) VALUES (10)
const int IntScale = 5;
const decimal DecimalScale = 5;
const decimal DecimalScale2 = 5.0m;
context.Set<MyTable>()
.Select(row => new
{
WithFloats = 0.5f + (row.MyIntValue * 5.0f), // 50.5
WithDecimals = 0.5m + (row.MyIntValue * 5.0m), // 51
WithDecimals2 = 0.5m + ((decimal)row.MyIntValue * 5.0m), // 50.5
WithDecimals3 = 0.5m + ((decimal)row.MyIntValue * IntScale), // 51
WithDecimals4 = 0.5m + ((decimal)row.MyIntValue * (decimal)IntScale) // 51
WithDecimals5 = 0.5m + ((decimal)row.MyIntValue * DecimalScale) // 51
WithDecimals6 = 0.5m + ((decimal)row.MyIntValue * DecimalScale2) // 50.5
})
.Single();
Z pewnością nie jest to oczekiwane/prawidłowe zachowanie? Oczekuję, że wartość WithDecimals będzie wynosiła 50,5 (nie 51). Czy przeoczyłem coś prostego? W jaki sposób mogę zagwarantować, że metoda WithoutDecimals nie zostanie zaokrąglona bez zmiany typu pozostałych stałych?
Wytworzona SQL dla WithFloats i WithDecimals (odpowiednio):
,CAST(0.5 AS REAL) + (CAST(MyIntValue AS REAL) * CAST(5 AS REAL)) AS WithFloats
,0.5 + (CAST(MyIntValue AS DECIMAL(19,0)) * CAST(5 AS DECIMAL(18))) AS WithDecimals
EF mapy System.Decimal do DECIMAL (18, 0) domyślnie, więc twoja wartość WithDecimals zostanie zaokrąglona do najbliższej liczby całkowitej. Wierzę, że istnieje sposób na zmianę tego domyślnego zachowania, zobacz np. ten komentarz: http://stackoverflow.com/a/27418286/189572 – Max
@Max: Dodanie domyślnej dokładności dziesiętnej wydaje się nie mieć żadnego efektu. Co więcej, gdyby dodać kolejną rzutowaną kolumnę z wyrażeniem: (0,5 m + wiersz.MójIntWartość), wynik będzie wynosił 10,5, więc zachowanie nie wydaje się być spowodowane domyślną dokładnością dziesiętną. – mindlessgoods
Interesujące. Wygląda jak obsada wiersza.MyIntValue na DECIMAL (19,0) jest problemem, działa z rzutowaniem na DECIMAL (18). Co stanie się, gdy rzucisz go w systemie C# w systemie dziesiętnym? '' 'WithDecimals = 0.5m + ((dziesiętny) wiersz.MyIntValue * 5.0m)' '' – Max