Pergunta

Eu estou confuso quanto à diferença. Sendo bastante novo para .Net, eu sei que posso consultar IEnumerables usando as extensões de Linq. Então, o que é este IQueryable e como é que diferem?


Veja também Qual é a diferença entre IQueryable [T] e IEnumerable [T]? que sobreposições com esta questão.

Foi útil?

Solução

IEnumerable<T> representa um forward-only cursor de T. NET 3.5 adicionado métodos de extensão que incluíram a LINQ standard query operators como Where e First, com todos os operadores que requerem predicados ou funções anônimas tomando Func<T>.

implementos IQueryable<T> os operadores de consulta padrão mesmo LINQ, mas aceita Expression<Func<T>> para predicados e funções anônimas. Expression<T> é uma árvore de expressão compilado, uma versão quebrada-up do método ( "half-compilado" se você) que pode ser analisado pelo provedor do queryable e utilizado em conformidade.

Por exemplo:

IEnumerable<Person> people = GetEnumerablePeople();
Person person = people.Where(x => x.Age > 18).FirstOrDefault();

IQueryable<Person> people = GetQueryablePeople();
Person person = people.Where(x => x.Age > 18).FirstOrDefault();

No primeiro bloco, x => x.Age > 18 é um método anônimo (Func<Person, bool>), que pode ser executado como qualquer outro método. Enumerable.Where vai executar o método uma vez para cada pessoa, yielding valores para os quais o método devolvidos true.

No segundo bloco, x => x.Age > 18 é uma árvore de expressão (Expression<Func<Person, bool>>), que pode ser pensado como "é propriedade da 'idade'> 18".

Isso permite que coisas como LINQ to SQL de existir, porque eles podem analisar a árvore de expressão e convertê-lo em SQL equivalente. E porque o provedor não precisa executar até o IQueryable é enumerado (ele implementa IEnumerable<T>, depois de tudo), ele pode combinar vários operadores de consulta (no exemplo acima Where e FirstOrDefault) para fazer escolhas mais inteligentes sobre como executar toda a consulta contra a fonte de dados subjacente (como usar SELECT TOP 1 em SQL).

Veja:

Outras dicas

Na vida real, se você estiver usando um ORM como LINQ to SQL

  • Se você criar um IQueryable, em seguida, a consulta pode ser convertida para SQL e executado no servidor de banco de dados
  • Se você criar um IEnumerable, em seguida, todas as linhas serão puxados para a memória como objetos antes de executar a consulta.

Em ambos os casos, se você não chamar um ToList() ou ToArray() em seguida, consulta será executada cada vez que é usado, por isso, por exemplo, você tem um IQueryable e você preencher 4 caixas de listagem a partir dele, a consulta será executado no banco de dados 4 vezes.

Além disso, se você estender sua consulta:

q.Select(x.name = "a").ToList()

Em seguida, com um IQueryable o SQL gerado conterá where name = "a", mas com uma IEnumerable muitos mais papéis será puxado para trás do banco de dados, então a verificação x.name = "a" será feito pela NET.

"A principal diferença é que os métodos de extensão definidos para IQueryable take Expression objetos em vez de Func objetos, ou seja, o delegado que recebe é uma árvore de expressão em vez de um método para invocar. IEnumerable é ótimo para trabalhar com coleções na memória, mas IQueryable permite uma fonte de dados remota, como um serviço de banco de dados ou web "

Fonte: aqui

IEnumerable IEnumerable é mais adequado para trabalhar com coleção na memória. não IEnumerable não se mover entre os itens, é a frente única coleção.

IQueryable melhores ternos IQueryable para fonte de dados remota, como um serviço de banco de dados ou web. IQueryable é uma característica muito poderosa que permite uma variedade de cenários de execução diferidos interessantes (como paginação e consultas composição base).

Então, quando você tem que simplesmente percorrer a coleção na memória, use IEnumerable, se você precisa fazer qualquer manipulação com a coleção como Dataset e outras fontes de dados, uso IQueryable

A principal diferença é que IEnumerable irá enumerar todos os seus elementos o tempo todo, enquanto IQueryable irá enumerar elementos, ou até mesmo fazer outras coisas, com base em uma consulta. A consulta é uma expressão (a representação de dados de código .Net), que um IQueryProvider deve explorar / interpretar / compilação / whatever, a fim de gerar resultados.

Ter uma expressão de consulta dá duas vantagens.

A primeira vantagem é a otimização. Porque modificadores como 'onde' estão incluídos na expressão de consulta, o IQueryProvider pode aplicar otimizações de outra forma impossíveis. Em vez de retornar todos os elementos, em seguida, jogando fora a maioria deles devido a uma cláusula 'onde', o provedor poderia usar uma tabela hash para localizar itens com uma determinada chave.

A segunda vantagem é a flexibilidade. Porque as expressões são estruturas de dados exploráveis, você pode fazer coisas como serialize a consulta e enviá-lo a um computador remoto (por exemplo. LINQ to SQL).

IQueriable é o mesmo que IEnumerable mas também fornece funcionalidade adicional para implementar a consulta com Linq personalizada. Eis a descrição no MSDN: http://msdn.microsoft. com / en-us / library / system.linq.iqueryable.aspx

Em primeiro lugar IEnumerable são encontrados em um Namespace System.Collections enquanto o IQueryable são encontrados em um Namespace System.Linq. Se você está a utilizar IEnumerable ao consultar dados de coleções na memória como List, coleção de matriz etc E ao consultar os dados de out-memória (como banco de dados remoto, serviço) coleções para que você são o uso IQueryable. Devido ao consultar os dados do banco de dados, IEnumerable executar consulta seleção no lado do servidor, carregar dados na memória no lado do cliente e, em seguida, filtrar dados. Daí faz mais trabalho e torna-se lenta. Ao consultar os dados do banco de dados, IQueryable executar consulta seleção no lado do servidor com todos os filtros. Assim funciona a menos e torna-se rapidamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top