Qual é a diferença entre “LINQ to Entities”, “LINQ to SQL” e “LINQ to Dataset”


91

Já trabalho há um bom tempo com o LINQ. No entanto, permanece um pouco um mistério quais são as diferenças reais entre os sabores de LINQ mencionados.

A resposta bem-sucedida conterá uma breve diferenciação entre eles. Qual é o objetivo principal de cada sabor, qual é o benefício e existe um impacto no desempenho ...

PS: Eu sei que existem muitas fontes de informação por aí, mas estou procurando uma espécie de "folha de dicas" que instrui um novato sobre onde se dirigir para um objetivo específico.


Respostas:


110
  • todos eles são LINQ - Language Integrated Query - então todos eles compartilham muitos pontos em comum. Todos esses "dialetos" basicamente permitem que você faça uma seleção de dados no estilo consulta, de várias fontes.

  • Linq-to-SQL é a primeira tentativa da Microsoft em um ORM - Mapeador Relacional de Objeto. Ele oferece suporte apenas ao SQL Server. É uma tecnologia de mapeamento para mapear tabelas de banco de dados SQL Server para objetos .NET.

  • Linq-to-Entities é a mesma ideia, mas usando o Entity Framework em segundo plano, como o ORM - novamente da Microsoft, mas com suporte a vários back-ends de banco de dados

  • Linq-to-DataSets é LINQ, mas o uso é contra o "estilo antigo" ADO.NET 2.0 DataSets - antes do ORM da Microsoft, tudo que você podia fazer com o ADO.NET era retornar DataSets, DataTables etc. e Linq -to-DataSets consulta esses armazenamentos de dados em busca de dados. Portanto, neste caso, você retornaria um DataTable ou DataSets (namespace System.Data) de um back-end de banco de dados e, em seguida, consultaria aqueles usando a sintaxe LINQ


1
Parabéns por 50k, agora você passou oficialmente muito tempo no StackOverflow. ;)
Aaronaught,

1
@Aaronaught: obrigado - e você está absolutamente certo! :-) Tem que deixar um vício para cada homem, não? Por favor?!?!?!
marc_s

1
marc_s, obrigado por esta resposta. Você pode dizer algo sobre desempenho. De sua resposta, eu diria que o Linq-to-Entities é o mais avançado e, portanto, provavelmente tem o melhor desempenho.
Marcel

2
@Marcel: da minha intuição (sem fatos concretos), eu diria: Linq-to-SQL ou é o mais rápido (apenas uma camada entre o banco de dados e o modelo de objeto), Linq-to-Dataset um segundo próximo e Linq-to -Entities é o último, porque Entity Framework sempre tem duas camadas de mapeamento (portanto, a maior complexidade). Mas, novamente: apenas um pressentimento, sem números para comprovar isso
marc_s

3
@marc_s Sei que esta é uma postagem antiga, mas LINQ to Entities provavelmente seria mais rápido do que LINQ to Dataset na maioria dos casos. LINQ to Dataset não é realmente um tipo, é LINQ sobre objetos dos quais você está usando o dataset como o objeto. Como o LINQ sobre objetos não executa nenhum SQL, primeiro você deve criar seu Conjunto de dados a partir da origem SQL, e o LINQ sobre objetos não pode ajudá-lo a realizar nenhuma otimização de consulta na recuperação de dados no conjunto de dados. Isso e os conjuntos de dados são péssimos em termos de desempenho, uma vez que todas as colunas estão encaixotadas e toda aquela mudança de tipo mata o desempenho.
Robert McKee

38

LINQ é um amplo conjunto de tecnologias, baseado em (por exemplo) uma sintaxe de compreensão de consulta, por exemplo:

var qry = from x in source.Foo
          where x.SomeProp == "abc"
          select x.Bar;

que é mapeado pelo compilador em código:

var qry = source.Foo.Where(x => x.SomeProp == "abc").Select(x => x.Bar);

e aqui começa a verdadeira magia. Observe que não dissemos o que Fooestá aqui - e o compilador não se importa! Contanto que ele possa resolver algum método adequado chamado Whereque possa receber um lambda, e o resultado disso tenha algum Select método que possa aceitar o lambda, ele está feliz.

Agora, considere que o lambda pode ser compilado tanto em um método anônimo (delegado, para LINQ-to-Objects, que inclui LINQ to DataSet), ou a uma expressão-árvore (um modelo de execução que representa o lambda em um modelo de objeto )

Para dados na memória (normalmente IEnumerable<T>), ele apenas executa o delegado - bem e rápido. Mas, para IQueryable<T>a representação de objeto da expressão (a LambdaExpression<...>), ele pode separá-la e aplicá-la a qualquer exemplo "LINQ-to-Something".

Para bancos de dados (LINQ-to-SQL, LINQ-to-Entities), isso pode significar escrever TSQL, por exemplo:

SELECT x.Bar
FROM [SomeTable] x
WHERE x.SomeProp = @p1

Mas pode (para ADO.NET Data Services, por exemplo) significar escrever uma consulta HTTP.

Executar uma consulta TSQL bem escrita que retorna uma pequena quantidade de dados é mais rápido do que carregar um banco de dados inteiro pela rede e, em seguida, filtrar no cliente. Ambos têm cenários ideais e cenários totalmente errados.

O objetivo e o benefício aqui é permitir que você use uma única sintaxe com verificação estática para consultar uma ampla gama de fontes de dados e tornar o código mais expressivo (código "tradicional" para agrupar dados, por exemplo, não é muito claro em termos do que está tentando fazer - está perdido na massa do código).


Marc, obrigado por este insight. No entanto, eu não perguntei sobre tais detalhes internos. -1, sinto muito, porque não responde a pergunta.
Marcel

7
Como alguém que está escrevendo seu próprio provedor de LINQ, esta é a melhor resposta que já vi até agora. Eu discordo sobre o -1.
Dan Barowy

30

LINQ significa consulta integrada de linguagem. Ele permite que você use a linguagem de consulta "estilo SQL" diretamente em C # para extrair informações de fontes de dados.

  • Essa fonte de dados pode ser um banco de dados do servidor SQL - este é Linq para SQL
  • Essa fonte de dados pode ser um contexto de dados de objetos de estrutura de entidade - Linq para entidades .
  • Essa fonte de dados pode ser conjuntos de dados ADO.net - Linq para Conjunto de Dados .

Essa fonte de dados também pode ser um arquivo XML - Linq to XML .
Ou mesmo apenas uma classe Collection de objetos simples - Linq to Objects .

LINQ descreve a tecnologia de consulta, o resto do nome descreve a origem dos dados que estão sendo consultados.

Para um pouco mais de fundo:

Conjuntos de dados são objetos ADO.net nos quais os dados são carregados de um banco de dados em um conjunto de dados .net e o Linq pode ser usado para consultar esses dados depois de carregados.

Com o Linq para SQL, você define classes .net que mapeiam para o banco de dados e o Linq para SQL cuida do carregamento dos dados do banco de dados do servidor SQL

E, finalmente, o framework Entity é um sistema onde você pode definir um banco de dados e mapeamento de objetos em XML e pode então usar o Linq para consultar os dados que são carregados por meio desse mapeamento.


3
na verdade, Linq-to-SQL é apenas SQL Server - não apenas "qualquer" back-end de banco de dados SQL.
marc_s

3
@marc_s: Bom local. Obrigado. Embora, se alguém estiver interessado, existem provedores Linq to sql de terceiros para outros bancos de dados, se você quiser. Consulte code2code.net/DB_Linq ou Google para outros. Não posso comentar sobre sua qualidade.
Simon P Stevens

1
Simon, obrigado especialmente por aquele resumo útil de 2 linhas da estrutura do Entitiy. +1
Marcel
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.