Repositoy Pattern - IQueryable vs IEnumerable


 E então, o que usar na implementação do Repository Pattern : IQueryable ou IEnumerable ?

Se você esta chegando agora e esta perdido, eu vou iniciar explicando a diferença entre IQueryable e IEnumerable.

A interface IQueryable<T> destina-se à implementação por provedores de consultas, e assim,  permite que você opere e crie consultas que podem ser enviadas para um provedor remoto, como Entity Framework e Linq to SQL que operam com IQueryable<T>,  pois eles vão traduzir a consulta para SQL e a seguir enviar para o banco de dados.

A utilização do IQueryable<T> permite a construção de árvores de expressões de consulta. É mais indicado para utilizar com banco de dados (LINQ TO SQL) e outras fontes remotas, principalmente quando precisa de paginação de resultados. Estas expressões podem ser obtidas e executadas com os métodos IQueryProvider.CreateQuery() e IQueryProvider.Execute().

Já a interface IEnumerable<T> permite que você execute consultas na memória.

Então se você esta trabalhando somente com coleção de dados em memória a interface IEnumerable é uma boa escolha, mas se você precisa consultar uma coleção de dados que esta conectada a um banco de dados, usar IQueryable pode ser a melhor escolha, pois ela reduz o tráfego de rede e usa a linguagem SQL.

Obs: Veja o meu artigo  .NET - Comparando IEnumerable com IQueryable  para mais detalhes.

Mas então qual delas devemos usar na implementação do padrão Repositório ?

Na verdade não existe uma resposta final e definitiva como : 'sempre use esta ou aquela.'

Em geral a resposta vai depender muito do que você quer fazer e do cenário no qual você vai implementar.

No entanto podemos fazer algumas considerações para te ajudar a decidir.

Vamos a elas..

Retornar IQueryable proporciona mais flexibilidade a quem vai consumir o repositório. Isso coloca a responsabilidade de reduzir os resultados para o cliente, o que pode ser um benefício, e, uma muleta.

O lado bom, é que você não vai precisar criar muitos métodos no repositório para obter os dados desejados. Assim, você pode colocar a lógica de recuperação fora do repositório e deixá-la ser usada da maneira que o usuário desejar.

Portanto, a exposição ao IQueryable oferece a maior flexibilidade e permite consultas eficientes, em oposição à filtragem na memória, etc., e pode reduzir a necessidade de criar vários métodos específicos de busca de dados.

Por outro lado, agora você deu a seus usuários muito poder. Eles podem fazer coisas que você pode não ter planejado (usar excessivamente .include(), fazer consultas pesadas e filtrar na memória em suas respectivas implementações, etc.).

Assim retornar IQueryable é mais conveniente se você quer e pode permitir e confiar que o lado do cliente vai criar consultas personalizadas a partir dos métodos do seu repositório.

Assim retornar IQueryable tem os seguintes pontos negativos:

E assim a grande diferença entre IEnumerable e  IQueryable é onde o filtro é executado. O primeiro executa na memória e e o outro executa no banco de dados.

Pense bem, o padrão de repositório nos dá uma representação clara por camadas e, mais importante, permite desacoplar a camada de acesso a dados permitindo que possamos mudar na fonte de dados sem problemas se houver essa necessidade.

Certo ?

A pergunta é " Existe a possibilidade de substituição da fonte de dados ?".

Se amanhã parte dos dados puder ser movida para serviços SAP, um banco de dados NoSQL ou simplesmente para arquivos de texto, você pode garantir a implementação adequada da interface IQueryable ?

Percebeu !!!! Porque usar IQueryable pode ser perigoso ?

Embora isso não seja um quesito que indique você nunca deva usar IQueryable é bom você saber que essas mazelas existem.

E estamos conversados.

"Porque não nos pregamos a nós mesmos, mas a Cristo Jesus, o Senhor; e nós mesmos somos vossos servos por amor de Jesus.
Porque Deus, que disse que das trevas resplandecesse a luz, é quem resplandeceu em nossos corações, para iluminação do conhecimento da glória de Deus, na face de Jesus Cristo."
2 Coríntios 4:5,6

Referências:


José Carlos Macoratti