Сериализовать IQueryable (пробросить объект по сети)
От: Nikolay_Ch Россия  
Дата: 28.07.14 07:07
Оценка: 3 (1)
Есть желание пробросить объект типа IQueryable через собственный шлюз TCP/IP. Нужно пробросить именно IQueryable, чтобы не делать кучу методов с параметрическим поиском и не тащить всю коллекцию на клиента, а передавать только то, что клиент запросил. Для этого надо его сериализовать. Сериализовать в лоб его не получается. Можно попробовать сериализовать Expression. Но что-то не нашел, как после десериализации его использовать. Кто может подсказать, куда вообще копать?
Re: Сериализовать IQueryable (пробросить объект по сети)
От: scale_tone Норвегия https://scale-tone.github.io/
Дата: 28.07.14 07:14
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:

> куда вообще копать?


Expression Tree Serializer.
Re: Сериализовать IQueryable (пробросить объект по сети)
От: Tom Россия http://www.RSDN.ru
Дата: 28.07.14 08:30
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>Есть желание пробросить объект типа IQueryable через собственный шлюз TCP/IP. Нужно пробросить именно IQueryable, чтобы не делать кучу методов с параметрическим поиском и не тащить всю коллекцию на клиента, а передавать только то, что клиент запросил. Для этого надо его сериализовать. Сериализовать в лоб его не получается. Можно попробовать сериализовать Expression. Но что-то не нашел, как после десериализации его использовать. Кто может подсказать, куда вообще копать?



Вам может проще OData использовать. Для 4-й версии на клиенте можно как раз сгенерировать IQueryable который будет транслировать вызовы в вызовы OData сервиса
Народная мудрось
всем все никому ничего(с).
Re: Сериализовать IQueryable (пробросить объект по сети)
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.07.14 09:19
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>Кто может подсказать, куда вообще копать?


Можно поглядеть в сторону linq2db, на то что в папочке ServiceModel.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
AVK Blog
Re[2]: Сериализовать IQueryable (пробросить объект по сети)
От: Nikolay_Ch Россия  
Дата: 28.07.14 10:18
Оценка:
Здравствуйте, scale_tone, Вы писали:

_>Expression Tree Serializer.

Уж пробовал, использовал List<>, взял от него IQueryable, сериализовал. Десериализовать не получилось.
Re[2]: Сериализовать IQueryable (пробросить объект по сети)
От: Nikolay_Ch Россия  
Дата: 28.07.14 10:20
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Вам может проще OData использовать. Для 4-й версии на клиенте можно как раз сгенерировать IQueryable который будет транслировать вызовы в вызовы OData сервиса

У меня уже есть отлаженный сервис, и это не WCF... Боюсь, что OData потребует больших телодвижений.
Re[2]: Сериализовать IQueryable (пробросить объект по сети)
От: Nikolay_Ch Россия  
Дата: 28.07.14 10:21
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Можно поглядеть в сторону linq2db, на то что в папочке ServiceModel.

У нас уже есть EF. Насколько оправданно применение еще и linq2db?
Re[3]: Сериализовать IQueryable (пробросить объект по сети)
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.07.14 10:29
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>У нас уже есть EF. Насколько оправданно применение еще и linq2db?


Не обязательно же весь linq2db применять. Исходники доступны, можно использовать ровно столько, сколько требуется.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
AVK Blog
Re[3]: Сериализовать IQueryable (пробросить объект по сети)
От: scale_tone Норвегия https://scale-tone.github.io/
Дата: 28.07.14 10:53
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>Здравствуйте, scale_tone, Вы писали:


_>>Expression Tree Serializer.

N_C>Уж пробовал, использовал List<>, взял от него IQueryable, сериализовал. Десериализовать не получилось.

Странно, что сериализовать получилось. Зачем сам IQueryable-объект сериализовать? Сериализуют/десериализуют Expression (запрос к нему, то бишь)!

Пример.
Re[2]: Сериализовать IQueryable (пробросить объект по сети)
От: IT Россия linq2db.com
Дата: 28.07.14 13:47
Оценка:
Здравствуйте, scale_tone, Вы писали:

_>Expression Tree Serializer.


У сериализации ET есть одна фундаментальная проблема — дерево может содержать представление кода, определённого только на клиенте. Тогда на сервере десериализовывать будет нечего. Т.е. это всё может работать, а может и не работать в зависимости от того какой код напишет программист.
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Сериализовать IQueryable (пробросить объект по сети)
От: scale_tone Норвегия https://scale-tone.github.io/
Дата: 28.07.14 14:30
Оценка:
Здравствуйте, IT, Вы писали:

> Т.е. это всё может работать, а может и не работать в зависимости от того какой код напишет программист.


Дык, кто ж спорит. Само собой.
Re[4]: Сериализовать IQueryable (пробросить объект по сети)
От: Nikolay_Ch Россия  
Дата: 29.07.14 08:11
Оценка:
Здравствуйте, scale_tone, Вы писали:

_>Здравствуйте, Nikolay_Ch, Вы писали:


N_C>>Здравствуйте, scale_tone, Вы писали:


_>>>Expression Tree Serializer.

N_C>>Уж пробовал, использовал List<>, взял от него IQueryable, сериализовал. Десериализовать не получилось.
_>Странно, что сериализовать получилось. Зачем сам IQueryable-объект сериализовать? Сериализуют/десериализуют Expression (запрос к нему, то бишь)!
Вот такой код — возвращает в итоге null

var ds = new List<string>() {"abc", "def", "ghi"};
var exp1 = ds.AsQueryable().Select(r => r);
var xml = exp1.SerializeQuery();
ExpressionSerializer es = new ExpressionSerializer();
var exp2 = es.Deserialize(xml);
return exp2;



А вот такой — приводит к эксепшну: "Invalid cast from 'System.String' to 'System.Linq.EnumerableQuery`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'"
var ds = new List<string>() {"abc", "def", "ghi"};
var exp1 = ds.AsQueryable().Select(r => r);
var xml = ExpressionSerializer.Serialize(exp1.Expression);
ExpressionSerializer es = new ExpressionSerializer();
var exp2 = es.Deserialize(xml);
return exp2;
Re[5]: Сериализовать IQueryable (пробросить объект по сети)
От: scale_tone Норвегия https://scale-tone.github.io/
Дата: 29.07.14 15:50
Оценка: 4 (1)
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>А вот такой — приводит к эксепшну: "Invalid cast from 'System.String' to 'System.Linq.EnumerableQuery`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'"


А надо как-то так:

public static IEnumerable<string> GetStrings()
{
    return new List<string>() { "abc", "def", "ghi" };
}

static void Main(string[] args)
{            
    Expression<Func<IEnumerable<string>>> exp1 = () => from s in GetStrings() select s;

    ExpressionSerializer es = new ExpressionSerializer(new TypeResolver(new[] { typeof(Program).Assembly }));
    var xml = es.Serialize(exp1);
    var exp2 = es.Deserialize(xml);
}


Впрочем, я не настаиваю. Либа — действительно не фонтан в плане удобства и качества.
Re[6]: Сериализовать IQueryable (пробросить объект по сети)
От: Nikolay_Ch Россия  
Дата: 30.07.14 11:20
Оценка:
Здравствуйте, scale_tone, Вы писали:

_> ExpressionSerializer es = new ExpressionSerializer(new TypeResolver(new[] { typeof(Program).Assembly }));

В последней версии библиотеки нет параметрического конструктора
Re[6]: Сериализовать IQueryable (пробросить объект по сети)
От: Nikolay_Ch Россия  
Дата: 30.07.14 11:26
Оценка:
Здравствуйте, scale_tone, Вы писали:

_> var xml = es.Serialize(exp1);

И метод Serialize стал статическим...
Re[3]: Сериализовать IQueryable (пробросить объект по сети)
От: Tom Россия http://www.RSDN.ru
Дата: 30.07.14 16:57
Оценка: +1
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>Здравствуйте, Tom, Вы писали:


Tom>>Вам может проще OData использовать. Для 4-й версии на клиенте можно как раз сгенерировать IQueryable который будет транслировать вызовы в вызовы OData сервиса

N_C>У меня уже есть отлаженный сервис, и это не WCF... Боюсь, что OData потребует больших телодвижений.
OData требует очень мало движений и не требует вообще WCF.
очень советую потратить некоторое время что бы разобраться.
Народная мудрось
всем все никому ничего(с).
Re[4]: Сериализовать IQueryable (пробросить объект по сети)
От: Nikolay_Ch Россия  
Дата: 31.07.14 07:31
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>OData требует очень мало движений и не требует вообще WCF.

Tom>очень советую потратить некоторое время что бы разобраться.
Хм... OData — это же протокол запроса обмена данными. Есть реализация преобразования IQueryable в запрос OData?
По сути, мне важна именно возможность динамического формирования фильтров для исходного списка данных.
Это можно реализовать через список параметрических методов, простой текстовой строкой со списком фильтров или через объект IQueryable. Сейчас меня интересует именно третий вариант.
Re[4]: Сериализовать IQueryable (пробросить объект по сети)
От: Nikolay_Ch Россия  
Дата: 31.07.14 07:36
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>OData требует очень мало движений и не требует вообще WCF.

Tom>очень советую потратить некоторое время что бы разобраться.
В дополнение — IQueryable мне нужен не только для фильтрации получаемых данных на сервере, но и для преобразований типов, которые доступны в LINQ-запроса.
Re[5]: Сериализовать IQueryable (пробросить объект по сети)
От: Tom Россия http://www.RSDN.ru
Дата: 02.08.14 10:38
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>Здравствуйте, Tom, Вы писали:


Tom>>OData требует очень мало движений и не требует вообще WCF.

Tom>>очень советую потратить некоторое время что бы разобраться.
N_C>Хм... OData — это же протокол запроса обмена данными. Есть реализация преобразования IQueryable в запрос OData?
Да.
http://blogs.msdn.com/b/odatateam/archive/2014/03/11/how-to-use-odata-client-code-generator-to-generate-client-side-proxy-class.aspx

N_C>По сути, мне важна именно возможность динамического формирования фильтров для исходного списка данных.

IQueryable + OData для этого идеальный случай, а на сервере EntityFramework, в итоге всей работы на всё пра всё час максимум.

N_C>Это можно реализовать через список параметрических методов, простой текстовой строкой со списком фильтров или через объект IQueryable. Сейчас меня интересует именно третий вариант.
Народная мудрось
всем все никому ничего(с).
Re[5]: Сериализовать IQueryable (пробросить объект по сети)
От: artelk  
Дата: 03.08.14 12:35
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>Хм... OData — это же протокол запроса обмена данными. Есть реализация преобразования IQueryable в запрос OData?

Есть, но OData несколько убог. Например, OrderBy после Select не работает. Постоянно будешь натыкаться на подобные ограничения.

@IT&Co: я правильно понимаю, что LinqService в linq2db полноценен (т.е. нет такого linq-запроса, который бы работал напрямую черезз DataConnection, но не работал удаленно через LinqService)?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.