.NET: come modificare il valore in una DataTable
-
06-07-2019 - |
Domanda
In ADO.NET sto usando GetSchemaTable per restituire la tabella dello schema per un set di risultati.
DataTable schema = rdr.GetSchemaTable();
gridSchema.DataSource = schema;
gridSchema.DataBind();
Sfortunatamente il valore " ProviderType " viene visualizzato come un numero intero, anziché come OleDbType valore di enumerazione che è:
ProviderType Desired Display Value
============ =====================
129 Char
3 Integer
129 Char
129 Char
3 Integer
3 Integer
129 Char
135 DBTimeStamp
129 Char
129 Char
...
Tutti questi numeri interi sono i valori di enumerazione per Enumerazione 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,
}
Voglio visualizzare il tipo di dati come qualcosa di leggibile dall'uomo, piuttosto che un numero intero.
Ho provato a scorrere lo schema DataTable e modificare i valori all'interno del 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();
Ma questo genera un'eccezione:
Column 'ProviderType' is read only.
Ho persino guardato RowDataBound , pensando che potrei cambiare il valore man mano che viene visualizzato:
protected void gridSchema_RowDataBound(object sender, GridViewRowEventArgs e)
{
//todo: magic
//e.Row["ProviderType"]
}
Ma non sembra che tu possa giocare con i valori renderizzati.
Qualcuno può suggerire un modo carino per molto con il valore della colonna ProviderType in modo che sia leggibile dall'uomo quando lo visualizzo agli umani?
Aggiornamento
La soluzione alternativa che sto usando in questo momento è virare su una colonna aggiuntiva alla fine:
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();
Soluzione
Potrei essere completamente fuori di qui, ma non puoi semplicemente impostare la proprietà ReadOnly della colonna su false? Come:
schema.Columns["ProviderType"].ReadOnly = false;
Successivamente potresti riscontrare un problema di tipo colonna mentre stai provando a inserire un valore stringa in una colonna intera. Ma questo dovrebbe portarti nella giusta direzione.
modifica
Risoluzione del problema relativo al tipo di colonna:
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);
}
Altri suggerimenti
Oppure potresti creare un oggetto con tutti i campi dal datatable, passare tutti i dati nel tuo oggetto e modificarlo o creare un campo di sola lettura che restituisce la stringa secondo il numero intero indicato.
GridView e altri accettano anche array di oggetti come origini dati, quindi è automatico.