Предоставить IQueryable поверх службы WCF
Я узнал о IQueryable и отложенной загрузке / отложенном выполнении запросов.
Можно ли выставить эту функциональность через WCF? Я хотел бы предоставить сервис LINQ-to-SQL, который возвращает IQueryable, который затем я могу выполнить на клиенте с помощью дополнительных запросов и, наконец, выполнить с помощью.ToList(). Формат OData применим вообще в этом контексте?
Если возможно, каков термин для этой техники и какими хорошими уроками я могу следовать? Спасибо.
6 ответов
Вам следует проверить службы данных WCF, которые позволят вам определить запрос Linq на клиенте. Службы данных WCF, вероятно, являются единственным решением для ваших требований.
IQueryable по-прежнему является только интерфейсом, и функциональность зависит от типа, реализующего интерфейс. Вы не можете напрямую выставлять запросы Linq-To-Sql или Linq-To-Entities. Существует несколько причин, таких как недолговечные контексты или сериализация, которые будут выполнять запрос, поэтому клиент получит список всех объектов вместо запроса.
Насколько я знаю, datacontext не сериализуем, это означает, что вы не можете передать его с WCF
Вы можете использовать http://interlinq.codeplex.com/ который позволяет отправлять запрос Linq через WCF.
Службы данных WCF могут использоваться только с webHttpBinding, и не все запросы Linq могут быть выражены. Написание запросов при использовании службы данных WCF не так привлекательно - требует строковых выражений, таких как:
.AddQueryOption("$filter", "Id eq 100");
https://remotelinq.codeplex.com/ это еще один выбор. Но он работает в AppDomain для сканирования текущих сборок и их сериализации. Эта технология не подходит для WinRT, так как нет доменов для WinRT App
Я боролся с тем же вопросом и понял, что правильно сформулированный вопрос - это решаемая проблема.
IQueryable в основном служит для фильтрации запроса перед отправкой его в ваш вызов БД, поэтому вместо получения 1000 записей и фильтрации только 10 вы получите эти 10 для начала. Эта фильтрация принадлежит вашему сервисному уровню, но если вы создаете API, я предполагаю, что вы сопоставите его с параметрами AND/OR в своем URL.
HTTP://{хост}/{объект} / д = имя джон и возраст =21.
Таким образом, вы получите что-то вроде этого:
Filter:Column1=Value1 > http://{host}/{entity}q?column1=value1 > SELECT *
FROM Entity
WHERE Column1=Value1
MVC > WCF > DB
Вы можете найти очень хороший образец [ здесь]
Наконец, поскольку ваша полезная нагрузка из WCF, скорее всего, будет JSON, вы можете (и должны) затем десериализовать их в своих моделях доменов внутри коллекции. Это происходит до тех пор, пока не произойдет подкачка страниц, поэтому я бы порекомендовал некоторое кэширование WCF (и, поскольку это HTTP, это действительно просто). Вы по-прежнему будете использовать LINQ на стороне WebApp, просто без предложения "WHERE" LINQ (если вы не хотите динамически создавать URL, указанный выше?)
Для сложного запроса ИЛИ вы в конечном итоге получите несколько запросов WCF (1 на "И"), а затем объедините их все вместе
Если возможно отправлять IQuerable<> через WCF, это не очень хорошо с точки зрения безопасности, так как IQuerable <> может предоставлять такие вещи, как строка подключения, к базе данных. Некоторые из предыдущих комментариев кажутся многообещающими.