Мое приложение имеет набор типов, реализующих IDataItem. Все они являются простыми типами «DTO», представляющими строки базы данных. Экземпляры создаются с использованием PetaPoco (микро ORM), запустив запрос SQL select к базе данных. Запрос выбора SQL специфичен для этого типа, а также зависит от номера версии приложения (предположим, что тип X имеет свойство Y, но до версии приложения N в базе данных нет соответствующего столбца - в этом случае запрос возвращает значение по умолчанию для тебя).Каждый тип, реализующий IDataItem, должен иметь связанную строку (SQL select qry), но доступ к ней до создания экземпляра типа
Характер приложения заключается в том, что существует много таких типов, и число будет расти в будущем. Я пытаюсь использовать generics на уровне доступа к данным, чтобы (i) минимизировать количество кода и (ii) заставлять будущих разработчиков создавать необходимые SQL-запросы по мере их создания.
Таким образом, в слое доступа к данным, что я хочу, это метод, который:
- имеет параметр типа T: IDataItem
- возвращает IEnumerable Т
- находит SQL запрос на выборку, связанный с T
- запускает запрос к БД с помощью PetaPoco для создания списка T (его немного сложнее, чем это - есть также предложение dynamic where, но оставляя это для упрощения)
Моя задача - как получить SQL-запрос для параметра типа T до создания любых экземпляров T. В идеале я бы добавил метод к IDataItem, например. string SqlSelectFrom (int appVersion), но тогда мне нужен экземпляр для его вызова (если только для интерфейса может потребоваться статический член!). Лучшее, что я есть сейчас функция внутри слоя доступа к данным, как это (но это не реально выполнить мое требование, чтобы заставить разработчиков будущих типов реализовать запрос SQL):
private string GetSqlSelectFrom<T>(int appVersion) where T : IDataItem
{
if (typeof(T) == typeof(ProductDto))
return "select ProductId, ProductCode from Product";
if (typeof(T) == typeof(ColourDto))
return "select ColourId, ColourCode from Colour";
etc
throw new Exception("No SQL defined!");
}
Есть ли лучше шаблон для этого?
Я могу представить себе два способа: (1) использование атрибута на классах DTO (2) с использованием вида реестра для типов DTO –
Атрибуты не будут работать, так как запрос может отличаться в зависимости от версии приложения. Объясните подробнее о регистрации plz? – Laurence