Как я могу передать лямбда-выражение в службу WCF? - PullRequest
16 голосов
/ 22 июня 2011

Мой текущий проект использует архитектуру IDesign, поэтому все мои слои являются сервисами. Я хотел, чтобы мой метод Read в CRUD моего уровня доступа к ресурсам принимал предикат в форме лямбда-выражения, а также список связанных объектов для извлечения. Таким образом, уровень доступа к ресурсам будет очень общим.

[OperationContract]
Result<MyObject> ReadObjects(Func<MyObject, bool> predicate, string[] includes);

Теперь я обнаружил нечто, что должно было быть очевидным, и это то, что я не могу сериализовать лямбда-выражения. Я изучил синтаксический анализ строки в лямбда-выражении, но это тоже бесполезно.

Можно ли использовать какой-либо метод для передачи лямбда-выражения в службу? Есть ли лучший способ сделать то, что я пытаюсь сделать?

Ответы [ 6 ]

25 голосов
/ 22 июня 2011

Мы должны решить эту проблему в LINQ-to-Just-About-Everything. Например, при выполнении LINQ-to-SQL:

var results = from c in customers where c.City == "London" select c.Name;

каким-то образом содержимое лямбд c=>c.City == "London" и c=>c.Name должно оказаться на сервере SQL в форме, понятной серверу. Ясно, что мы не можем сохранить лямбды на сервере.

Вместо этого мы превращаем лямбды в деревья выражений, анализируем деревья выражений во время выполнения, строим из него фактическую строку SQL и отправляем эту строку на сервер для обработки.

Вы можете сделать то же самое. Создайте язык запросов для вашего сервера. На стороне клиента превратите лямбды в деревья выражений. Проанализируйте их во время выполнения, превратите результат в строку на языке запросов, а затем отправьте запрос в службу.

Если вам интересно, как это работает в LINQ, архитектор LINQ-to-SQL Мэтт Уоррен написал большую серию статей в блоге о том, как сделать это самостоятельно:

http://blogs.msdn.com/b/mattwar/archive/2008/11/18/linq-links.aspx

6 голосов
/ 22 июня 2011

Возможно, динамический запрос будет работать в вашей ситуации?

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Вы передадите строку условия where в службу, которая проверит и преобразует ее в выражение

4 голосов
/ 22 июня 2011

WCF не предлагает это из коробки. По сути, вам придется написать собственный сериализатор, который будет принимать лямбда-выражения и превращать дерево выражений в сериализуемый фрагмент данных.

Так работает WCF DataServices. Вы используете лямбда-выражения в своем клиентском коде, он разбивает эти лямбда-выражения на строки, которые он передает по строке запроса в службу данных, которая затем превращает строку обратно в лямбду, которую он применяет к IQueryable на стороне сервера.

Выполнимо, но для этого вам придется написать много кода для сериализации. Кроме того, давайте проясним, что это будут выражения lamdba , а не полные лямбда-методы, содержащие случайный код, который может быть выполнен на стороне сервера.

0 голосов
/ 09 сентября 2015

Я обнаружил, что проект с открытым исходным кодом в codeplex является решением этой проблемы как субъект

Сериализатор дерева выражений

Описание проекта библиотеки классов .NET 4.0 и Silverlight 4который сериализует и десериализует экземпляры Expression.Кроме того: WCF IQueryable поставщик LINQ и Web Http (REST) ​​клиент для Silverlight, который предоставляет упрощенный клиентский API REST (то есть WebChannelFactory WCF), который проще в использовании, чем WebClient.

по этой ссылке

http://expressiontree.codeplex.com/

0 голосов
/ 28 июля 2011

Создайте Объект запроса и передайте его вашим службам.

Посмотрите, поможет ли это:

http://ruijarimba.wordpress.com/2011/05/09/entity-framework-and-t4-generate-query-objects-on-the-fly-part-1/

Пример:

var search = new AlbumSearch();
search.PriceFrom = 5;
search.PriceTo = 10;
search.Artist = new ArtistSearch(){ Name = "Metallica" };
search.Genre = new GenreSearch(){ NameContains = "Metal" };

var albuns = from x in repository.All<Album>(search.GetExpression())
                  select x;
0 голосов
/ 22 июня 2011

Я использую эту библиотеку в CodePlex для сериализации / десериализации деревьев выражений (но в предыдущей версии), и она выполняет свою работу.

Здесь также есть некоторые другие подобные вопросыone: Сериализация и десериализация деревьев выражений в C #

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...