.NET: Cómo cambiar el valor en una DataTable
-
06-07-2019 - |
Pregunta
En ADO.NET estoy usando GetSchemaTable para devolver la tabla de esquema para un conjunto de resultados.
DataTable schema = rdr.GetSchemaTable();
gridSchema.DataSource = schema;
gridSchema.DataBind();
Desafortunadamente, el valor " ProviderType " se muestra como un entero, en lugar de OleDbType valor de enumeración que es:
ProviderType Desired Display Value
============ =====================
129 Char
3 Integer
129 Char
129 Char
3 Integer
3 Integer
129 Char
135 DBTimeStamp
129 Char
129 Char
...
Todos estos enteros son los valores de enumeración para Enumeración OleDbType :
public enum OleDbType
{
Empty = 0,
SmallInt = 2,
Integer = 3,
Single = 4,
Double = 5,
Currency = 6,
Date = 7,
BSTR = 8,
IDispatch = 9,
Error = 10,
Boolean = 11,
Variant = 12,
IUnknown = 13,
Decimal = 14,
TinyInt = 16,
UnsignedTinyInt = 17,
UnsignedSmallInt = 18,
UnsignedInt = 19,
BigInt = 20,
UnsignedBigInt = 21,
Filetime = 64,
Guid = 72,
Binary = 128,
Char = 129,
WChar = 130,
Numeric = 131,
DBDate = 133,
DBTime = 134,
DBTimeStamp = 135,
PropVariant = 138,
VarNumeric = 139,
VarChar = 200,
LongVarChar = 201,
VarWChar = 202,
LongVarWChar = 203,
VarBinary = 204,
LongVarBinary = 205,
}
Quiero mostrar el tipo de datos como algo legible por los humanos, en lugar de un número entero.
He intentado recorrer el esquema DataTable y modificar los valores dentro de DataTable:
DataTable schema = rdr.GetSchemaTable();
//Change providerType column to be readable
foreach (DataRow row in schema.Rows)
{
OleDbType t = (OleDbType)row["ProviderType"];
row["ProviderType"] = t.ToString();
}
gridSchema.DataSource = schema;
gridSchema.DataBind();
Pero eso arroja una excepción:
Column 'ProviderType' is read only.
incluso miré el evento RowDataBound , pensando que podría cambiar el valor a medida que se representa:
protected void gridSchema_RowDataBound(object sender, GridViewRowEventArgs e)
{
//todo: magic
//e.Row["ProviderType"]
}
Pero no parece que puedas jugar con valores renderizados.
¿Alguien puede sugerir una buena manera de hacer mucho con el valor de la columna ProviderType para que sea legible para los humanos cuando lo muestro a los humanos?
Actualizar
La solución que estoy usando ahora es agregar una columna adicional al final:
DataTable schema = rdr.GetSchemaTable();
schema.Columns.Add("OleDbDataType", typeof(String));
schema.Columns.Add("CLRDataType", typeof(String));
foreach (DataRow row in schema.Rows)
{
//Show the actual provider type
OleDbType t = (OleDbType)row["ProviderType"];
row["OleDbDataType"] = t.ToString();
//Show the corresponding CLR type while we're doing a hack
row["CLRDataType"] = row["DataType"].ToString();
}
gridSchema.DataSource = schema;
gridSchema.DataBind();
Solución
Podría estar completamente fuera de aquí, pero ¿no puede simplemente establecer la propiedad ReadOnly de la columna en false? Me gusta:
schema.Columns["ProviderType"].ReadOnly = false;
Después, puede tener un problema de tipo de columna cuando intenta poner un valor de cadena en una columna entera. Pero esto debería llevarte a la dirección correcta.
edit:
Solución del problema de tipo de columna:
DataTable newTable = schema.Clone();
newTable.Columns["ProviderType"].DataType = typeof(string);
foreach (DataRow dr in schema.Rows)
{
DataRow newRow = newTable.NewRow();
// fill newRow with correct data and newly formatted providertype
newTable.Rows.Add(newRow);
}
Otros consejos
O podría crear un objeto con todos los campos de la tabla de datos, pasar todos los datos a su objeto y modificarlo o crear un campo de solo lectura que devuelva la cadena de acuerdo con el entero dado.
GridView y otros también aceptan matrices de objetos como fuentes de datos, por lo que es automático.