ИМХО, я думаю, вы зашли слишком далеко с абстракцией структуры таблицы.Чрезмерное использование интерфейсов может затруднить чтение кода.Например, меня очень раздражает, что вы не можете нажать F12, чтобы увидеть реализацию объекта, потому что это тип интерфейса.
Проверенная модель, с которой я работал годами и которую очень легко поддерживать, заключается в том, чтобы все имена классов были идентичны именам таблиц, а затем именам полей, которые соответствуют именам столбцов.Затем вы можете легко генерировать методы, просто используя поиск и замену в редакторе, и то же самое касается изменений кода.Таким образом, вам не нужно хранить имена столбцов и индексы столбцов в памяти.Вы просто жестко закодируете их на своем уровне доступа к данным (HARDCODING НЕ ВСЕГДА ПЛОХО!).Например:
this.Price = reader["Price"] as decimal?;
При таком подходе производительность очень хорошая, а код супер сопровождаемый!
Какой бы подход вы ни использовали, ключевой момент заключается в том, как сохранить отображения из столбцов таблицы в класс.свойства.Я рекомендую жестко их кодировать и использовать прямое соглашение об именах (имя столбца = имя свойства).Этот подход требует, чтобы вы перекомпилировали при добавлении или изменении столбцов, но я думаю, что эти изменения не происходят достаточно часто, чтобы оправдать наличие имен столбцов в переменных или чтение их из отдельного файла.Это позволяет избежать перекомпиляции, но делает код менее понятным.Я не думаю, что это того стоит.