I want to be able to enter SQL into a textbox and display the results in a WPF Datagrid. I thought to start with an SqlDataReader
, and set the datagrid's ItemsSource
to the data reader:
using (var cmd = conn.CreateCommand()) {
cmd.CommandText = sql.Text;
sqlResults.ItemsSource = cmd.ExecuteReader();
}
but this fails with the following error: Invalid attempt to call FieldCount when reader is closed
, which I understand to mean that by the time WPF gets around to reading the FieldCount
property of the row object, the using
block has already been exited.
So I tried using LINQ and ToList
, to get something that would persist in memory:
sqlResults.ItemsSource = cmd.ExecuteReader().Cast<DbDataRecord>().ToList();
but this only displays the 'FieldCount' for each row, which is apparently the only property which DbDataRecord
has.
Some solutions I have considered:
- Bind to a DataTable instead of a DataReader? But I don't need editing capabilities.
- Select each row into an in-memory data structure? What data structure could I use? I can't use anonymous types, because the names and types of the columns change based on the SQL statement. If I use
List<object>
, how will the datagrid know to generate columns for each object in the list? - Create a custom type descriptor? It seems like overkill.
But I feel the solution should be very simple and easy. Am I missing something basic here?