Выполнение существующего запроса LINQ для динамического объекта (например, DataTable)
Я работаю над универсальным провайдером OData, чтобы пойти против обычного провайдера данных, который у нас здесь. Это полностью динамично в том, что я запрашиваю у поставщика данных таблицу, которую он знает. У меня пока есть базовая структура хранения на основе примера кода OData.
Моя проблема заключается в следующем: OData поддерживает запросы и ожидает от меня реализации IQueryable. С другой стороны, у меня нет поддержки запросов. Не шутка - провайдер возвращает таблицы и предложение WHERE не поддерживается. Производительность здесь не проблема - таблицы маленькие. Разбирать их можно в провайдере OData.
Моя главная проблема заключается в следующем.
- Я отправляю инструкцию SQL, чтобы получить данные таблицы. Результатом является своего рода устройство чтения данных ADO.NET.
- Мне нужно предоставить реализацию IQueryable для этих данных, чтобы потенциально разрешить последующую фильтрацию.
Есть идеи, как лучше всего это коснуться? Только для.NET 3.5 (4.0 не планируется в течение некоторого времени). Я серьезно думал о создании динамических классов DTO для каждой таблицы (с использованием байт-кода), чтобы я мог использовать стандартный LINQ. Сейчас я использую словарь для каждой записи (не слишком эффективный), но я не вижу реального способа фильтрации / сортировки по ним.
2 ответа
Пабло Кастро, один из основных участников OData, говорит, что предоставление услуги OData без возможности запроса полностью соответствует их намерениям. Смотрите этот пост в блоге.
Это одна из причин, по которой я действительно желаю, чтобы они внедрили ссылку "поиск" в ответе OData, чтобы клиентское приложение могло определить, были ли доступны возможности запросов или нет. Что-то вроде OpenSearch.
<Link rel="search" type="application/ODataQuery+xml" href="QueryMetadata.xml"/>
Таким образом, клиент может легко обнаружить, реализован поиск или нет.
Если вы в порядке с выполнением запроса внутри вашего провайдера OData, вы можете просто загрузить свои данные в список T (T является типом объекта), а затем просто вернуть list.AsQueryable(). Это вернет запрос LINQ to Objects, который обеспечивает полную поддержку всех параметров запроса и основан на хранении в памяти (список). Обратите внимание, что для правильной работы ваш IDataServiceQueryProvider.IsNullPropagationRequired должен возвращать true (поскольку LINQ to Objects требует, чтобы значения null были правильно переданы через запрос). Также, если вы установите в любом случае CanReflectOnInstanceProperty значение false, вам нужно будет выполнить некоторую переписывание запроса. Если это так, взгляните на этот пост здесь для объяснения того, как осуществляется доступ к свойствам.