WCF+NHibernate+LINQ = ???

Интересная на мой взгляд задача… Допустим у нас есть клиенты и сервер, общающиеся по WCF. Мы не хотим на клиентах деплоить сборки NHibernate и всего что с ним связано (в случае например, если клиенты написаны на Silverlight — это очень актуально), однако хотим воспользоваться некоторыми видами запросов с клиентской стороны (типа Criteria в Nhibernate).

Как к этому подступиться?

Попробуем разобраться по порядку. NHibernate устроен так, что создает прокси-объекты в пределах сессии, эти прокси объекты конечно же нельзя передавать через DataContract (так как они в принципе не помечены DataContractAttribute). Прокси нужны нам для того, чтобы разрешить ленивую загрузки, и тп. Это проблема номер раз… Вывод — запретить прокси (default-lazy = false). Как показывает практика, даже при запрещении default-lazy, прокси все равно создаются. Кроме того NHibernate использует специализированные типы для хранения коллекций, такие как GenericBag и т.п. Это добро тоже не может передаваться в WCF канал.

Сделав такие выводы, я было очень сильно огорчился и хотел уже переходить на EF 😉

Видимо скоро я так и поступлю (но по другим соображениям), однако данная статья направлена на то, чтобы подтолкнуть нас на правильную мысль.

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

Вторая проблема, о которой я здесь скажу — специализированные запросы с критериями и условиями (Criteria). Я захотел сделать здесь более универсальную возможность и прикрутить к NHibernate старый добрый LINQ, потому как LINQ есть LINQ 😉

Но:

1) LINQ — язык выражений (класс Expression), которые нельзя сериализировать штатным способом.

2) NHibernate в настоящий момент не поддерживает LINQ.

Второй минус решился использованием NHContrib — в которой есть либа LINQ2NHibernate (УРА!!)

Первый минус — решается использованием Dynamic LINQ. Выражение на клиенте записывается в строку, а затем на сервере — парсится специальным классом.

Отлично. Еще один нюанс, на который стоит обратить внимание — использование generic’ов. Как вы знаете, в WCF есть ограничение на этот счет. Как здесь поступить? Ответ: пользоваться классом NetDataContractSerializer для сериализациидесериаоизации тела сообщения.

Ну в общем то вот такие вот перед нами стоят проблемы, будем решать их по порядку 😉

Продолжение следует…

Рейтинг
( Пока оценок нет )
Загрузка ...