Подтвердить что ты не робот

Как передать лямбда-выражение в службу WCF?

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

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

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

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

4b9b3361

Ответ 2

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

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

каким-то образом содержимое lambdas 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

Ответ 3

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

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

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

Ответ 5

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

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

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;

Ответ 6

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

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

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

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

http://expressiontree.codeplex.com/