简体   繁体   中英

C# datatable decimal with precision

I have this code to add new column to datatable:

DataColumn col = new DataColumn("column", typeof(decimal));      
col.Caption = "Column";
mytable.Columns.Add(col);

How can I specify decimal precision for this column so the value will always be in the format I want it to be?

I had this same problem myself, and I fixed it by loading the whole schema on app startup, and then referencing the column information from the schema as I needed it.

I only have a Visual Basic example, but hopefully it's pretty easy to translate to C#

Setup

' 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

Usage

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)

You can not. However, you can format the value when you retrieve it from the table using String.Format function:

String.Format("{0:0.##}", (Decimal) myTable.Rows[rowIndex].Columns[columnIndex]); 

This answer is the C# version of NullVoxPopuli's answer. Since I needed this I thought I'd share it and save people some time.

It loads the schema into a DataColumnCollection that is then added to the new DataTable. If you want to reuse the column definitions you could split the two parts into functions.

        var ConnectionString = "bla";
        DataColumnCollection Columns;
        
        using (SqlConnection con = new SqlConnection(ConnectionString))
        {
            con.Open();
            using(SqlCommand command = new SqlCommand("select top 1 * from trades", con))
            {
                using (var r = command.ExecuteReader())
                {
                    using(var dt = new DataTable())
                    {
                        dt.Load(r);
                        Columns = dt.Columns;
                    }
                }
                
            }
            con.Close();
        }
        
        
        
        DataTable DataTable = new DataTable();
        while(Columns.Count > 0)
        {
            DataColumn c = Columns[0];
            c.Table.Columns.Remove(c);

            DataTable.Columns.Add(c);
        }
        Columns = DataTable.Columns;
        
        // use DataTable;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM