Однажды у меня была похожая проблема, когда мне приходилось передавать миллионы строк по WCF. То, что сработало для меня, это чанкинг канал.
На стороне сервера ваш класс реализует что-то вроде этого:
void InitQuery(QueryString); // initializes datareader that pulls result out of DB
YourClass[] GetChunk(int ChunkSize); // puts the next x elements from the reader into array. If it returns null you're done.
С клиента вы устанавливаете запрос с первым, а затем читаете куски со второго. Вам не нужно беспокоиться о разбивке по страницам и т. Д. В запросе sql, просто получите следующие x записей из читателя, поместите их в ваш класс DataContract и верните его. SqlDataReader отслеживает, где вы находитесь. (Это может не очень хорошо масштабироваться для многих пользователей, хотя)
Убедитесь, что вы используете прокси на сервере между обращениями к серверу, поскольку он поддерживает состояние. Посмотрите в SessionMode.
Кроме того, я получил огромный прирост производительности, запустив его через TCP и работая с настройками безопасности.
Вы не упомянули, что вы используете, WinForms или WPF, но оба поддерживают способы отложенной загрузки данных в сетку. Вы хотите вызвать GetChunk из фонового потока, и, когда у него будут результаты, передать весь массив в поток пользовательского интерфейса, а затем зациклить его. (Не зацикливайте его из фонового потока, потому что вам нужно будет вызывать каждую строку в массиве. Это будет медленно)
Просто кое-что, что я усвоил ему нелегко, дайте мне знать, если вам нужны подробности где-нибудь.