Reading reader.GetValue(2) works, but nothing in it says "price". And if someone changes the order of the columns in the SELECT, every index silently points at the wrong value.
The reader knows more than the values. reader.FieldCount is the number of columns in the row, and reader.GetName(i) is the name of column i. A loop over the columns can then pair each name with its value, so no index is ever written by hand. For example, with a table books:
var cmd = library.CreateCommand();
cmd.CommandText = "SELECT title, year FROM books";
using var reader = cmd.ExecuteReader();
reader.Read();
for (int i = 0; i < reader.FieldCount; i++) {
Console.WriteLine($"{reader.GetName(i)} = {reader.GetValue(i)}");
}
// title = Dune
// year = 1965
You put that loop in a small function, RowToDict, which turns the reader's current row into a dictionary whose keys are the column names. Since the code no longer depends on the order of the columns, the query can ask for all of them with SELECT *. The products' stock comes along too.
GET / → 200 Welcome to the shop!
GET /products → 200 [{"id": 1, "name": "Mug", "price": 12, "category": "kitchen", "stock": 10},
{"id": 2, "name": "Notebook", "price": 7, "category": "office", "stock": 0},
… 8 products in all …
{"id": 8, "name": "Gift card", "price": 50, "category": null, "stock": 999}]
Your task: write the function RowToDict that turns a row into a dictionary keyed by column name, ask for every column of products, and build each product with RowToDict(reader) instead of index numbers.
Assignment
Follow the Coding Tutorial to write RowToDict and switch the shop to SELECT *.
Hint
Inside RowToDict, the key is reader.GetName(i), and the value is null when reader.IsDBNull(i), else reader.GetValue(i).
Free plan: 30 tutor messages. PRO is unlimited.
