У меня есть приложение, которое позволяет пользователю динамически запрашивать любую службу OData и возвращать им конкретные столбцы, которые они запрашивали внутри сетки. После нескольких недель исследований я закончил использование Simple.OData.Client, чтобы запросить услугу. Чтобы вернуть данные, у меня есть модель, которая определяет, что нужно сделать. Вот то, что имеет отношение к моему вопросу:IEnumerable <IDictionary <string, object >> to IQueryable
- BaseUrl (Service адрес)
- ИМЯ_СПИСКА (таблица/список для запроса против)
- Столбцы (Список)
- ODataColumnPath (Путь к I данных хотите)
- ColumnDataType (тип данных, возвращаемых/должны быть поданы в)
- FRIENDLYNAME (что-то дружественное использовать)
- C alculationType (Enum
None, Count, Sum, Min, Max
)
Теперь ODataColumnPath
может быть столь же просто, как «ProductName» или быть столь же сложным, как «Категория/Product/Заказы/OrderID» возвращать одно поле или вернуть много. Когда он возвращает много значений, я делаю с ним какие-то вычисления.
В настоящее время я создаю DataTable
путем рекурсивного цикла (while loop) через все IEnumerable<IDictionary<string, object>>
с, пока не получу значения, которые я ищу. Затем я использую данные XML для создания столбцов DataTable, а затем заполняю строки из цикла. Этот подход работает отлично, но я должен думать, что есть лучший способ сделать это.
Теперь, когда я выполняю запрос, я ищу в LinqPad, подключающемся непосредственно к a Northwind odata service. Я возвращаюсь к объекту IQueryable<Anonymous>
.
LINQPad -> Борей
Products.Select (x => new { x.ProductID, x.ProductName, x.Category.CategoryName })
URL запроса
http://demos.telerik.com/kendo-ui/service/Northwind.svc/Products() $ расширение = Категория & $ выберите = ProductID, ProductName, категория/CategoryName
Использование библиотеки OData? упомянутые выше, я возвращаю те же данные, но как IEnumerable<IDictionary<string, object>>
Код
ODataClient client = new ODataClient(new ODataClientSettings { UrlBase = "http://demos.telerik.com/kendo-ui/service/Northwind.svc/", OnTrace = (a, b) => { string.Format(a, b).Dump("Trace Event"); } });
var data = await client.For("Products").Expand("Category").Select("ProductID,ProductName,Category/CategoryName").FindEntriesAsync().Dump();
URL запроса (от события трассировки)
http://demos.telerik.com/kendo-ui/service/Northwind.svc/Products?$ Расширение = Категория & $ выберите = ProductID, ProductName, категория/CategoryName
Теперь, если я указываю сильно типизированных класс, я вернусь такой же, как IQueryable
сделал (с небольшой дополнительной работы):
var strongly = (await client
.For<Product>()
.Expand(x => x.Category)
.Select(x => new { x.ProductID, x.ProductName, x.Category.CategoryName })
.FindEntriesAsync())
.Select(x => new { x.ProductID, x.ProductName, x.Category.CategoryName })
.Dump();
Что бы я хотел получить, это анонимный объект списка или динамический объект. Оттуда я могу при необходимости применить свои вычисления. Есть ли способ динамически определить класс и передать его в статический метод For<T>(...)
?
Хотя я провел недели, исследуя эту тему, чтобы в конечном итоге использовать Simple.OData.Client, я открыт для использования другого метода получения моих данных.