Dans notre application réelle, nous obtenons une exception OverflowException lorsque vous essayez de convertir la valeur SqlDecimal de 99 en System.Decimal. L'exception est levée car la précision de SqlDecimal est supérieure à la précision de System.Decimal.
Voici un test qui reproduit le problème:
[Test] public void SqlDecimalToDecimalOverflowTest() { // in our real application d1 & d2 are loaded from a database; both are declared as DECIMAL(28, 5) // for test purposes I recreate identical SqlDecimal objects here: var d1 = new SqlDecimal(28, 5, true, 9900000, 0, 0, 0); // Debugger shows {99.00000} var d2 = new SqlDecimal(28, 5, true, 100000, 0, 0, 0); // Debugger shows {1.00000} var d3 = d1.Value / d2; // Debugger shows d1.Value as {99}, d1.Value is of type decimal (not SqlDecimal) var exception = d3.Value; // Debugger shows d3 as {99.0000000000000000000000000000000} }
Une capture d'écran:
La question est:
Quel est le moyen le plus rapide de convertir de tels objects SqlDecimal en Decimal?
Il y a quelque time, j'ai écrit cette méthode d'aide:
public static SqlDecimal RecreateWithMinPrecScale(this SqlDecimal value) { ssortingng s = value.Scale > 0 ? value.ToSsortingng().TrimEnd('0') : value.ToSsortingng(); int delimiterIndex = s.IndexOf("."); int precision = s.Length - (delimiterIndex >= 0 ? 1 : 0) - (s.StartsWith("-") ? 1 : 0); int scale = delimiterIndex >= 0 ? s.Length - 1 - delimiterIndex : 0; return SqlDecimal.ConvertToPrecScale(value, precision, scale); }
donc je peux écrire
var ok = d3.RecreateWithMinPrecScale().Value; // no exception
Mais évidemment, c'est une méthode lente et inefficace et nous devons faire des milliards de calculs de ce genre.
S'il vous plaît, ne discutons pas pourquoi nous utilisons la class SqlDecimal et pas seulement System.Decimal (c'est une application financière et je crois qu'auparavant nous avions des exigences pour supporter de très longs nombres (grands ou précis) et il a été dit que 28-29 numbers de System.Decimal peut ne pas suffire).
Vous devez restaurer les valeurs des attributes de précision et d'échelle dans le d3
après l'opération de division:
var d3 = d1.Value / d2; d3 = SqlDecimal.ConvertToPrecScale(d3, 28, 5);