.NET 保存到数据库会截断我的小数而不是四舍五入。可能会出现什么问题?

.NET saving to DB truncates my decimals instead of rounds them.. what could be possible problems?

我没有使用 entity framework,但我使用的是 Microsoft Enterprise Library。

我有一个像这样的值:1.125979843654984 被截断为 1.125,而不是四舍五入为 1.126

该值所在列的精度为 Decimal(5,3)。

发生这种情况的原因有哪些?

我可以提供任何其他信息来帮助您吗?

我是 .NET 新手。

更新 1

调用保存过程的代码:

Dim dsCalcGroupByBand As New DataSet
dsCalcGroupByBand.Tables.Add(dtCalcGroupByBand)
dsCalcGroupByBand.Tables(0).TableName = "Table"
Dal.SaveGridDataSet(dsCalcGroupByBand, "Select * from tblLTDCalcGroupByBand where iGroupKY=" & GroupData.GroupNo, False, False)

变量中的method方法Dal:

Public Function SaveGridDataSet(ByVal pDS As DataSet, ByVal pSQL As String, _
    Optional ByVal pCheckIsNewGroup As Boolean = True, _
    Optional ByVal pForceAsNewGroup As Boolean = False, _
    Optional ByVal pSQLDelete As String = "") As Boolean

  Dim DA As New SqlDataAdapter
  Dim commandBuilder As SqlCommandBuilder
  Dim adapter As SqlDataAdapter
  Dim updatedRows As Integer

  Using connection As SqlConnection = _database.CreateConnection()

    Try
      If ((pCheckIsNewGroup = True) And (GroupData.isNewGroup = True)) Or _
      (pForceAsNewGroup = True) Then
        pDS = IsNewGroup(pDS)
      End If
      DA = New SqlDataAdapter(pSQL, connection) '_database.GetDataAdapter
      ' Make the CommandBuilder generate the insert, update, and delete commands.
      commandBuilder = New SqlCommandBuilder(DA)

      ' Save the changes.
      DA.Update(pDS)

    Catch e As InvalidOperationException
      Try
        ' it's horrible to run code, in here, but there need to be tests
        ' implemented before modifying the above code.
        adapter = New SqlDataAdapter(pSQL, connection)
        commandBuilder = New SqlCommandBuilder(adapter)
        'adapter.SelectCommand = commandBuilder.GetUpdateCommand
        updatedRows = adapter.Update(pDS)
      Catch ee As DBConcurrencyException
        ' there was no change (data already exists, no need to update)
        Console.WriteLine("no data written")
      End Try

    Catch e As DBConcurrencyException

      ' Delete the current records using the optional delete pSQLDelete
      If pSQLDelete = "" Then
        pSQLDelete = pSQL.Replace("Select *", "Delete")
      End If
      UpdateSQL(pSQLDelete)

      ' Now Create the dataset as if a new group and try the update again
      DA.Update(IsNewGroup(pDS))
    Catch e As Exception

      Console.WriteLine("Un-mitigated exception")
      Console.WriteLine(e.Message)
    End Try


  End Using


End Function

以上面的小数为例: 在 dtCalcGroupByBand DataTable 中,存在一行值 1.125979843654984 的字段对应于数据库中数据类型为 Decimal(5,3) 的列——但是,特定的对应 DataColumn 对象是数据类型 System.Decimal - 这可能是问题的来源?也许?

无论如何,一旦保存,(在调用 Dal.SaveGridDataSet(...) 之后),我在 table 中查找值,它显示 1.125(截断)而不是 1.126(四舍五入)

更新 2

使用 Microsoft Enterprise Library(或其他访问数据库的 OO 方式),如何检索列的精度?

该列声明为 Decimal(5,3),因此您将在小数值右侧获得 3 位精度,其余部分将被截断。

如果要对值进行舍入,则必须在将其保存到数据库之前在数据表列中round,或者在正在执行的SQL 语句中对其进行舍入。

我解决了在应用程序启动时加载整个架构,然后根据需要从架构中引用列信息的问题。

希望其他人不必像我一样搜索解决这个问题。

设置

' in whatever class you do your database communication:
Private _database As SqlDatabase
Private Shared _schema As DataTable

Sub New()
  ' or however you handle the connection string / database creation
  Dim connectionString as String = GetConnectionString()
  _database = New SqlDatabase(connectionString)

  RetrieveSchema()
End Sub


Private Function RetrieveSchema() as DataTable
  If _schema Is Nothing Then
    Using connection As SqlConnection = _database.CreateConnection()
      connection.Open()
      _schema = connection.GetSchema("Columns")
    End Using
  End If

  return _schema
End Function


Public Function GetColumnInformation(tableName As String, columnName As String) as DataRow
  Dim firstMatchingRow as DataRow = (
    From row In _schema.Rows _
    Where (
      row("TABLE_NAME") = tableName AndAlso row("COLUMN_NAME") = columnName)
    )).FirstOrDefault()

  Return firstMatchingRow
End Function

用法

Dim columnInformation As DataRow = Dal.GetColumnInformation(tableName, columnName)

' find the precision
Dim precision = columnInformation("NUMERIC_PRECISION")
Dim scale = columnInformation("NUMERIC_SCALE")

' convert the decimal to the column's format
' e.g.: 2.345 with a scale of 2 would result in 
'       2.35
value = Decimal.Round(value, scale)