Pergunta

Dei uma olhada na postagem "Guia para iniciantes em LINQ" aqui no StackOverflow (Guia para iniciantes em LINQ), mas tinha uma pergunta complementar:

Estamos prestes a iniciar um novo projeto onde quase todas as nossas operações de banco de dados serão recuperações de dados bastante simples (há outro segmento do projeto que já grava os dados).A maioria dos nossos outros projetos até agora utiliza procedimentos armazenados para essas coisas.No entanto, gostaria de aproveitar o LINQ to SQL se fizer mais sentido.

Então, a questão é esta:Para recuperações simples de dados, qual abordagem é melhor, LINQ to SQL ou procedimentos armazenados?Algum pró ou contra específico?

Obrigado.

Foi útil?

Solução

Algumas vantagens do LINQ sobre o sprocs:

  1. Digite segurança:Acho que todos nós entendemos isso.
  2. Abstração:Isto é especialmente verdadeiro com LINQ para entidades.Essa abstração também permite que a estrutura adicione melhorias adicionais das quais você pode aproveitar facilmente. PLINQ é um exemplo de adição de suporte multithreading ao LINQ.As alterações no código são mínimas para adicionar esse suporte.Seria MUITO mais difícil fazer esse código de acesso a dados que simplesmente chama sprocs.
  3. Suporte para depuração:Posso usar qualquer depurador .NET para depurar as consultas.Com o sprocs, você não pode depurar facilmente o SQL e essa experiência está amplamente vinculada ao fornecedor do seu banco de dados (o MS SQL Server fornece um analisador de consultas, mas muitas vezes isso não é suficiente).
  4. Agnóstico de fornecedor:O LINQ funciona com muitos bancos de dados e o número de bancos de dados suportados só aumentará.Sprocs nem sempre são portáveis ​​entre bancos de dados, seja por causa da sintaxe variável ou do suporte a recursos (se o banco de dados suportar sprocs).
  5. Implantação:Outros já mencionaram isso, mas é mais fácil implantar um único assembly do que implantar um conjunto de sprocs.Isso também está de acordo com o nº 4.
  6. Mais fácil:Você não precisa aprender T-SQL para acessar dados, nem precisa aprender a API de acesso a dados (por exemplo,ADO.NET) necessário para chamar o arquivo sprocs.Isso está relacionado aos itens 3 e 4.

Algumas desvantagens do LINQ vs sprocs:

  1. Tráfego de rede:sprocs precisa apenas serializar o nome do sproc e os dados do argumento durante a conexão enquanto o LINQ envia a consulta inteira.Isso pode ficar muito ruim se as consultas forem muito complexas.No entanto, a abstração do LINQ permite que a Microsoft melhore isso ao longo do tempo.
  2. Menos flexível:Sprocs pode aproveitar ao máximo o conjunto de recursos de um banco de dados.O LINQ tende a ser mais genérico em seu suporte.Isso é comum em qualquer tipo de abstração de linguagem (por exemplo,C# versus montador).
  3. Recompilando:Se precisar fazer alterações na forma como você acessa os dados, será necessário recompilar, versionar e reimplantar seu assembly.Sprocs pode às vezes permitir que um DBA ajuste a rotina de acesso a dados sem a necessidade de reimplantar nada.

Segurança e capacidade de gerenciamento também são assuntos que as pessoas discutem.

  1. Segurança:Por exemplo, você pode proteger seus dados confidenciais restringindo o acesso diretamente às tabelas e colocando ACLs nos sprocs.Com o LINQ, entretanto, você ainda pode restringir o acesso direto às tabelas e, em vez disso, colocar ACLs em tabelas atualizáveis. Visualizações para alcançar um fim semelhante (supondo que seu banco de dados suporte visualizações atualizáveis).
  2. Capacidade de gerenciamento:O uso de visualizações também oferece a vantagem de proteger seu aplicativo contra alterações de esquema (como normalização de tabela).Você pode atualizar a visualização sem precisar alterar seu código de acesso a dados.

Eu costumava ser um grande cara do sproc, mas estou começando a me inclinar para o LINQ como uma alternativa melhor em geral.Se houver algumas áreas onde os sprocs são claramente melhores, provavelmente ainda escreverei um sproc, mas acessá-lo usando LINQ.:)

Outras dicas

Geralmente sou um defensor de colocar tudo em procedimentos armazenados, por todos os motivos pelos quais os DBAs vêm insistindo há anos.No caso do Linq, é verdade que não haverá diferença de desempenho com consultas CRUD simples.

Mas tenha algumas coisas em mente ao tomar essa decisão:usar qualquer ORM acopla você firmemente ao seu modelo de dados.Um DBA não tem liberdade para fazer alterações no modelo de dados sem forçá-lo a alterar o código compilado.Com procedimentos armazenados, você pode ocultar esses tipos de alterações até certo ponto, uma vez que a lista de parâmetros e o(s) conjunto(s) de resultados retornados de um procedimento representam seu contrato, e as entranhas podem ser alteradas, desde que esse contrato ainda seja cumprido .

E também, se o Linq for usado para consultas mais complexas, ajustar o banco de dados se torna uma tarefa muito mais difícil.Quando um procedimento armazenado está lento, o DBA pode focar totalmente no código isoladamente, e tem muitas opções, apenas para que o contrato ainda seja satisfeito quando for concluído.

Já vi muitos casos em que problemas sérios em um aplicativo foram resolvidos por alterações no esquema e no código em procedimentos armazenados, sem qualquer alteração no código compilado e implantado.

Talvez uma abordagem híbrida fosse boa com o Linq?O Linq pode, é claro, ser usado para chamar procedimentos armazenados.

Linq para SQL.

O servidor SQL armazenará em cache os planos de consulta, portanto não há ganho de desempenho para sprocs.

Suas instruções linq, por outro lado, farão parte logicamente e serão testadas com seu aplicativo.Sprocs estão sempre um pouco separados e são mais difíceis de manter e testar.

Se eu estivesse trabalhando em um novo aplicativo do zero agora, usaria apenas o Linq, sem sprocs.

Para recuperação básica de dados, eu optaria pelo Linq sem hesitação.

Desde que mudei para o Linq, descobri as seguintes vantagens:

  1. Depurar meu DAL nunca foi tão fácil.
  2. A segurança do tempo de compilação quando seu esquema muda não tem preço.
  3. A implantação é mais fácil porque tudo é compilado em DLLs.Chega de gerenciar scripts de implantação.
  4. Como o Linq pode suportar consultas de qualquer coisa que implemente a interface IQueryable, você poderá usar a mesma sintaxe para consultar XML, objetos e qualquer outra fonte de dados sem precisar aprender uma nova sintaxe.

LINQ irá inchar o cache do procedimento

Se um aplicativo estiver usando LINQ to SQL e as consultas envolverem o uso de cadeias de caracteres que podem ter comprimento altamente variável, o cache do procedimento do SQL Server ficará inchado com uma versão da consulta para cada comprimento de cadeia de caracteres possível.Por exemplo, considere as seguintes consultas muito simples criadas na tabela Person.AddressTypes no banco de dados AdventureWorks2008:

var p = 
    from n in x.AddressTypes 
    where n.Name == "Billing" 
    select n;

var p = 
    from n in x.AddressTypes 
    where n.Name == "Main Office" 
    select n;

Se ambas as consultas forem executadas, veremos duas entradas no cache de procedimento do SQL Server:Um vinculado a um NVARCHAR(7) e o outro a um NVARCHAR(11).Agora imagine se houvesse centenas ou milhares de strings de entrada diferentes, todas com comprimentos diferentes.O cache do procedimento ficaria desnecessariamente preenchido com todos os tipos de planos diferentes para exatamente a mesma consulta.

Mais aqui: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=363290

Acho que o argumento pró LINQ parece vir de pessoas que não têm histórico de desenvolvimento de banco de dados (em geral).

Especialmente se estiver usando um produto como VS DB Pro ou Team Suite, muitos dos argumentos apresentados aqui não se aplicam, por exemplo:

Mais difícil de manter e testar:VS fornece verificação completa de sintaxe, verificação de estilo, verificação referencial e de restrições e muito mais.Ele também fornece recursos completos de teste de unidade e ferramentas de refatoração.

O LINQ torna impossível o verdadeiro teste de unidade, pois (na minha opinião) ele falha no teste ACID.

A depuração é mais fácil no LINQ:Por que?O VS permite a integração completa do código gerenciado e depuração regular de SPs.

Compilado em uma única DLL em vez de scripts de implantação:Mais uma vez, o VS vem em socorro, pois pode construir e implantar bancos de dados completos ou fazer alterações incrementais seguras nos dados.

Não precisa aprender TSQL com LINQ:Não, não precisa, mas você precisa aprender LINQ - onde está o benefício?

Eu realmente não vejo isso como um benefício.Ser capaz de mudar algo isoladamente pode parecer bom em teoria, mas só porque as mudanças cumprem um contrato não significa que estejam retornando os resultados corretos.Para poder determinar quais são os resultados corretos, você precisa de contexto e obtém esse contexto do código de chamada.

Hum, aplicativos fracamente acoplados são o objetivo final de todos os bons programadores, pois eles realmente aumentam a flexibilidade.Ser capaz de mudar as coisas isoladamente é fantástico, e são seus testes de unidade que garantirão que ainda retornem resultados apropriados.

Antes que todos fiquem chateados, acho que o LINQ tem seu lugar e um grande futuro.Mas para aplicativos complexos e com uso intensivo de dados, não creio que esteja pronto para substituir os procedimentos armazenados.Esta foi uma visão que eu compartilhei com um MVP da TechEd este ano (eles permanecerão anônimos).

EDITAR:O lado do procedimento armazenado do LINQ to SQL é algo sobre o qual ainda preciso ler mais - dependendo do que encontrar, posso alterar minha diatribe acima;)

LINQ é novo e tem seu lugar.O LINQ não foi inventado para substituir o procedimento armazenado.

Aqui vou me concentrar em alguns mitos e CONTRAS de desempenho, apenas para "LINQ to SQL", é claro que posso estar totalmente errado ;-)

(1) As pessoas dizem que a instrução LINQ pode "armazenar em cache" no servidor SQL, para não perder desempenho.Parcialmente verdade."LINQ to SQL" na verdade é o tempo de execução que traduz a sintaxe LINQ para a instrução TSQL.Portanto, do ponto de vista do desempenho, uma instrução SQL ADO.NET codificada não tem diferença em relação ao LINQ.

(2) Dado um exemplo, uma IU de atendimento ao cliente tem uma função de "transferência de conta".esta função em si pode atualizar 10 tabelas de banco de dados e retornar algumas mensagens de uma só vez.Com o LINQ, você precisa construir um conjunto de instruções e enviá-las como um lote para o SQL Server.o desempenho deste lote LINQ->TSQL traduzido dificilmente pode corresponder ao procedimento armazenado.Razão?como você pode ajustar a menor unidade da instrução no procedimento armazenado usando o SQL Profiler integrado e a ferramenta de plano de execução, você não pode fazer isso no LINQ.

A questão é que, ao falar de uma única tabela de banco de dados e um pequeno conjunto de dados CRUD, o LINQ é tão rápido quanto o SP.Mas para uma lógica muito mais complicada, o procedimento armazenado é mais ajustável em termos de desempenho.

(3) "LINQ to SQL" facilmente faz com que os novatos introduzam consumidores de desempenho.Qualquer especialista sênior em TSQL pode dizer quando não usar CURSOR (basicamente você não deve usar CURSOR em TSQL na maioria dos casos).Com o LINQ e o charmoso loop "foreach" com consulta, é muito fácil para um novato escrever esse código:

foreach(Customer c in query)
{
  c.Country = "Wonder Land";
}
ctx.SubmitChanges();

Você pode ver que este código fácil e decente é muito atraente.Mas nos bastidores, o tempo de execução do .NET apenas traduz isso em um lote de atualização.Se houver apenas 500 linhas, será um lote TSQL de 500 linhas;Se houver milhões de linhas, isso é um sucesso.É claro que usuários experientes não usarão esse método para fazer esse trabalho, mas a questão é que é muito fácil cair dessa maneira.

O melhor código é nenhum código, e com procedimentos armazenados você precisa escrever pelo menos algum código no banco de dados e código no aplicativo para chamá-lo, enquanto com LINQ to SQL ou LINQ to Entities, você não precisa escrever nenhum código adicional. código além de qualquer outra consulta LINQ além de instanciar um objeto de contexto.

O LINQ definitivamente tem seu lugar em bancos de dados específicos de aplicativos e em pequenas empresas.

Mas numa grande empresa, onde as bases de dados centrais servem como um hub de dados comuns para muitas aplicações, precisamos de abstração.Precisamos gerenciar centralmente a segurança e mostrar históricos de acesso.Precisamos ser capazes de fazer análises de impacto:se eu fizer uma pequena alteração no modelo de dados para atender a uma nova necessidade comercial, quais consultas precisarão ser alteradas e quais aplicativos precisarão ser testados novamente?Visualizações e procedimentos armazenados me dão isso.Se o LINQ puder fazer tudo isso e tornar nossos programadores mais produtivos, serei bem-vindo - alguém tem experiência em usá-lo nesse tipo de ambiente?

Um DBA não tem liberdade para fazer alterações no modelo de dados sem forçar você a alterar seu código compilado.Com procedimentos armazenados, você pode ocultar esse tipo de alteração até certo ponto, uma vez que a lista de parâmetros e os resultados dos resultados retornados de um procedimento representam seu contrato, e as entranhas podem ser alteradas, desde que esse contrato ainda seja cumprido .

Eu realmente não vejo isso como um benefício.Ser capaz de mudar algo isoladamente pode parecer bom em teoria, mas só porque as mudanças cumprem um contrato não significa que estejam retornando os resultados corretos.Para poder determinar quais são os resultados corretos, você precisa de contexto e obtém esse contexto do código de chamada.

IMHO, RAD = LINQ, RUP = Procs armazenados.Trabalhei para uma grande empresa da Fortune 500 por muitos anos, em vários níveis, incluindo gerenciamento e, francamente, nunca contrataria desenvolvedores RUP para fazer desenvolvimento RAD.Eles estão tão isolados que têm um conhecimento muito limitado sobre o que fazer em outros níveis do processo.Com um ambiente isolado, faz sentido dar aos DBAs controle sobre os dados através de pontos de entrada muito específicos, porque outros francamente não conhecem as melhores maneiras de realizar o gerenciamento de dados.

Mas as grandes empresas movem-se dolorosamente lento na área do desenvolvimento, e isso é extremamente dispendioso.Há momentos em que você precisa se mover mais rápido para economizar tempo e dinheiro, e o LINQ oferece isso e muito mais.

Às vezes penso que os DBAs são tendenciosos contra o LINQ porque sentem que isso ameaça a segurança do seu emprego.Mas essa é a natureza da besta, senhoras e senhores.

Eu acho que você precisa usar procs para qualquer coisa real.

A) Escrever toda a sua lógica em linq significa que seu banco de dados é menos útil porque somente seu aplicativo pode consumi-lo.

B) De qualquer forma, não estou convencido de que a modelagem de objetos seja melhor que a modelagem relacional.

C) Testar e desenvolver um procedimento armazenado em SQL é muito mais rápido do que um ciclo de compilação e edição em qualquer ambiente do Visual Studio.Você acabou de editar, F5 e clicar em selecionar e você estará pronto para as corridas.

D) É mais fácil gerenciar e implantar procedimentos armazenados do que assemblies.você acabou de colocar o arquivo no servidor e pressionar F5...

E) Linq to sql ainda escreve código de baixa qualidade às vezes quando você não espera.

Honestamente, acho que o melhor seria a MS aumentar o t-sql para que ele pudesse fazer uma projeção de junção implicitamente, como o linq faz.t-sql deve saber se você deseja fazer order.lineitems.part, por exemplo.

O LINQ não proíbe o uso de procedimentos armazenados.Eu usei o modo misto com LINQ-SQL e LINQ-storedproc.Pessoalmente, estou feliz por não ter que escrever os procs armazenados...pwet-tu.

Além disso, há a questão de uma possível reversão 2.0.Acredite em mim, isso aconteceu comigo algumas vezes, então tenho certeza de que aconteceu com outras pessoas.

Também concordo que a abstração é o melhor.Junto com o fato, o propósito original de um ORM é fazer com que o RDBMS corresponda perfeitamente aos conceitos OO.No entanto, se tudo funcionou bem antes do LINQ, tendo que se desviar um pouco dos conceitos OO, então dane-se.Conceitos e realidade nem sempre se encaixam bem.Não há espaço para militantes fanáticos em TI.

Presumo que você queira dizer Linq To Sql

Para qualquer comando CRUD é fácil traçar o perfil do desempenho de um procedimento armazenado versus um procedimento armazenado.qualquer tecnologia.Neste caso, qualquer diferença entre os dois será insignificante.Tente criar o perfil de um objeto de campo de 5 (tipos simples) em mais de 100.000 consultas selecionadas para descobrir se há uma diferença real.

Por outro lado, o verdadeiro problema será saber se você se sente confortável em colocar sua lógica de negócios em seu banco de dados ou não, o que é um argumento contra procedimentos armazenados.

Segundo os gurus, defino LINQ como motocicleta e SP como carro.Se você quiser fazer uma viagem curta e tiver apenas passageiros pequenos (neste caso 2), vá normalmente com o LINQ.Mas se você quer viajar e tem banda grande, acho que deveria escolher SP.

Concluindo, a escolha entre moto ou carro depende do trajeto (negócio), duração (tempo) e passageiros (dados).

Espero que ajude, posso estar errado.:D

Todas essas respostas voltadas para o LINQ falam principalmente sobre FACILIDADE DE DESENVOLVIMENTO, que está mais ou menos ligada à má qualidade de codificação ou preguiça na codificação.Eu sou apenas assim.

Algumas vantagens do Linq, li aqui como fáceis de testar, fáceis de depurar, etc., mas não estão conectadas à saída final ou ao usuário final.Isso sempre causará problemas de desempenho para o usuário final.Qual é o sentido de carregar muitas coisas na memória e depois aplicar filtros ao usar o LINQ?

Novamente, TypeSafety alerta que "temos o cuidado de evitar a conversão de tipos errada", que, novamente, é de baixa qualidade e estamos tentando melhorar usando o linq.Mesmo nesse caso, se alguma coisa no banco de dados mudar, por ex.tamanho da coluna String, então o linq precisa ser recompilado e não seria seguro sem isso.Tentei.

Embora tenhamos achado bom, agradável, interessante etc. ao trabalhar com LINQ, ele tem a desvantagem de tornar o desenvolvedor preguiçoso :) e está provado 1000 vezes que é ruim (pode ser pior) no desempenho em comparação com Stored Procs.

Pare de ser preguiçoso.Estou me esforçando.:)

Processos armazenados versus código (Discussão anterior)

Para operações CRUD simples com um único ponto de acesso a dados, eu diria que opte pelo LINQ se você se sentir confortável com a sintaxe.Para uma lógica mais complicada, acho que os sprocs são mais eficientes em termos de desempenho se você for bom em T-SQL e em suas operações mais avançadas.Você também tem a ajuda do Tuning Advisor, SQL Server Profiler, depurando suas consultas do SSMS etc.

O procedimento armazenado facilita o teste e você pode alterar a consulta sem tocar no código do aplicativo.Também com o linq, obter dados não significa que sejam os dados corretos.E testar a exatidão dos dados significa executar o aplicativo, mas com o procedimento armazenado é fácil testar sem tocar no aplicativo.

O resultado pode ser resumido como

LinqToSql para sites pequenos e protótipos.Isso realmente economiza tempo para prototipagem.

Sps:Universal.Posso ajustar minhas consultas e sempre verificar ActualExecutionPlan/EstimatedExecutionPlan.

Create PROCEDURE userInfoProcedure
    -- Add the parameters for the stored procedure here
    @FirstName varchar,
    @LastName varchar
AS
BEGIN

    SET NOCOUNT ON;

    -- Insert statements for procedure here
    SELECT FirstName  , LastName,Age from UserInfo where FirstName=@FirstName
    and LastName=@FirstName
END
GO

http://www.totaldotnet.com/Article/ShowArticle121_StoreProcBasic.aspx

Tanto o LINQ quanto o SQL têm seus lugares.Ambos têm suas desvantagens e vantagens.

Às vezes, para recuperação complexa de dados, você pode precisar de processos armazenados.E às vezes você pode querer que outras pessoas usem seu processo armazenado no Sql Server Management Studio.

Linq to Entities é ótimo para desenvolvimento rápido de CRUD.

Claro que você pode criar um aplicativo usando apenas um ou outro.Ou você pode misturar tudo.Tudo se resume às suas necessidades.Mas os processos armazenados em SQL não irão desaparecer tão cedo.

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