O Entity Framework é adequado para sites de alto tráfego?

176

O Entity Framework 4 é uma boa solução para um site público com potencial de 1000 hits / segundo?

No meu entendimento, a EF é uma solução viável para sites menores ou de intranet, mas não seria escalável facilmente para algo como um site popular da comunidade (eu sei que o SO está usando LINQ to SQL, mas ... eu gostaria de mais exemplos / provas. ..)

Agora estou na encruzilhada da escolha de uma abordagem pura do ADO.NET ou do EF4. Você acha que a produtividade aprimorada do desenvolvedor com a EF vale o desempenho perdido e o acesso granular do ADO.NET (com procedimentos armazenados)? Algum problema sério que um site de alto tráfego pode enfrentar, estava usando a EF?

Agradeço antecipadamente.

niaher
fonte
1
Você não entende de escala. Escalar significa obter uma taxa de transferência de 10x quando você adiciona capacidade de 10x. Por que a EF evitaria que isso acontecesse? Ele adiciona um fator constante de sobrecarga a qualquer carga de trabalho do banco de dados.
usr

Respostas:

152

Depende um pouco da quantidade de abstração necessária . Tudo é um compromisso; por exemplo, EF e NHibernate introduzir uma grande flexibilidade para representar os dados em modelos interessantes e exóticos - mas como resultado eles fazer adicionar uma sobrecarga. Sobrecarga visível.

Se você não precisa alternar entre provedores de banco de dados e diferentes layouts de tabela por cliente, e se seus dados são lidos principalmente , e se você não precisa usar o mesmo modelo no EF, SSRS , ADO.NET Data Services, etc - então, se você quiser um desempenho absoluto como sua medida-chave, poderá fazer muito pior do que olhar para o dapper . Em nossos testes baseados no LINQ-to-SQL e no EF, descobrimos que o EF é significativamente mais lento em termos de desempenho de leitura bruta, provavelmente devido às camadas de abstração (entre o modelo de armazenamento etc.) e à materialização.

Aqui no SO, somos obsessivo-compulsivos em relação ao desempenho bruto e estamos felizes em sofrer o impacto do desenvolvimento de perder alguma abstração para ganhar velocidade. Como tal, nossa ferramenta principal para consultar o banco de dados é dapper . Isso nos permite usar nosso modelo LINQ-SQL pré-existente, mas simplesmente: é mais rápido. Nos testes de desempenho, é essencialmente exatamente o mesmo desempenho que escrever todo o código ADO.NET (parâmetros, leitores de dados, etc.) manualmente, mas sem o risco de errar o nome da coluna. É, no entanto, baseado em SQL (embora seja um prazer usar SPROCs se esse for o seu veneno escolhido). A vantagem disso é que não processamento adicional envolvido, mas é um sistema para pessoas que gostam de SQL. O que eu considero: não é uma coisa ruim!

Uma consulta típica, por exemplo, pode ser:

int customerId = ...
var orders = connection.Query<Order>(
    "select * from Orders where CustomerId = @customerId ",
    new { customerId }).ToList();

que é conveniente, seguro para injeção, etc. - mas sem toneladas de gosma do leitor de dados. Observe que, embora possa lidar com partições horizontais e verticais para carregar estruturas complexas, ele não suporta carregamento lento (mas: somos grandes fãs de carregamento muito explícito - menos surpresas).

Observe nesta resposta que não estou dizendo que a EF não é adequada para trabalhos de alto volume; Simplesmente: eu sei que dapper depende disso.

Marc Gravell
fonte
25
+1 para dapper. Usar um ORM complexo para modelos de leitura é apenas desnecessário. A abordagem que adotamos agora é usar um ORM para o nosso modelo de domínio (onde o material ORM sofisticado é realmente útil) e adequado para o nosso modelo de leitura. Isso contribui para aplicações super rápidas.
2
@ Marc, obrigado pela ótima resposta - posso finalmente tomar minha decisão com confiança! Definitivamente analisarei o dapper com mais detalhes posteriormente. Realmente gosto de como ele é apenas um arquivo :)
3
Eu escrevi meu próprio ORM. É lento. Olhei para dapper e gostei. Agora eu uso dapper para todas as minhas leituras e meu próprio ORM para inserções (que suporta FK, transações e todas as coisas boas). É o código mais fácil e legível que já escrevi.
2
@ acidzombie24 dapper suporta transações, e a parte de contribuição do dapper (que não faz parte do nuget deploy) está obtendo opções de inserção etc. Apenas mencionando a integridade. Estou feliz que dapper foi útil.
Marc Gravell
1
@anyname Eu nunca fiz um curso em vídeo sobre nenhum tópico; existem alguns vídeos por aí, mas não por mim. I tendem a ser uma palavra pessoa escrito
Marc Gravell
217

A questão "qual ORM devo usar" está realmente direcionada para a ponta de um enorme iceberg quando se trata da estratégia geral de acesso a dados e da otimização de desempenho em um aplicativo de larga escala.

Todas as seguintes coisas ( aproximadamente em ordem de importância) afetarão a taxa de transferência e todas elas são tratadas (às vezes de maneiras diferentes) pela maioria das principais estruturas ORM existentes:

  1. Design e Manutenção de Banco de Dados

    Esse é, por uma ampla margem, o determinante mais importante da taxa de transferência de um aplicativo ou site orientado a dados, e muitas vezes totalmente ignorado pelos programadores.

    Se você não usar técnicas adequadas de normalização, seu site estará condenado. Se você não tiver chaves primárias, quase todas as consultas serão lentas. Se você usar anti-padrões conhecidos, como o uso de tabelas para pares de valor-chave (AKA Entity-Attribute-Value) sem um bom motivo, explodirá o número de leituras e gravações físicas.

    Se você não tirar proveito dos recursos que o banco de dados oferece, como compactação de página, FILESTREAMarmazenamento (para dados binários), SPARSEcolunas, hierarchyidhierarquias e assim por diante (todos os exemplos do SQL Server), você não verá nenhum lugar próximo ao desempenho que você poderia estar vendo.

    Você deve começar a se preocupar com sua estratégia de acesso a dados depois de projetar seu banco de dados e se convencer de que é o melhor possível, pelo menos por enquanto.

  2. Carregamento ansioso x preguiçoso

    A maioria dos ORMs usava uma técnica chamada carregamento lento para relacionamentos, o que significa que, por padrão, ele carrega uma entidade (linha da tabela) de cada vez e faz uma ida e volta ao banco de dados toda vez que precisar carregar um ou muitos chave) linhas.

    Isso não é uma coisa boa ou ruim, mas depende do que realmente será feito com os dados e do quanto você sabe de antemão. Às vezes, o carregamento lento é absolutamente a coisa certa a fazer. O NHibernate, por exemplo, pode decidir não consultar nada e simplesmente gerar um proxy para um ID específico. Se tudo o que você precisa é o próprio ID, por que pedir mais? Por outro lado, se você estiver tentando imprimir uma árvore de cada elemento em uma hierarquia de três níveis, o carregamento lento se tornará uma operação O (N²), o que é extremamente ruim para o desempenho.

    Um benefício interessante do uso de "SQL puro" (ou seja, consultas brutas do ADO.NET / procedimentos armazenados) é que basicamente obriga a pensar exatamente sobre quais dados são necessários para exibir uma determinada tela ou página. ORMs e características carregamento lento não impedir você de fazer isso, mas eles não dão-lhe a oportunidade de ser ... bem, preguiçoso , e acidentalmente explodir o número de consultas que você executar. Portanto, você precisa entender os recursos de carregamento rápido dos ORMs e estar sempre atento ao número de consultas que você está enviando ao servidor para qualquer solicitação de página.

  3. Armazenamento em cache

    Todos os principais ORMs mantêm um cache de primeiro nível, AKA "cache de identidade", o que significa que, se você solicitar a mesma entidade duas vezes por seu ID, ele não precisará de uma segunda ida e volta e também (se você projetou seu banco de dados corretamente ) oferece a capacidade de usar simultaneidade otimista.

    O cache L1 é bastante opaco no L2S e EF, é preciso confiar que está funcionando. NHibernate é mais explícito sobre isso ( Get/ Loadvs. Query/ QueryOver). Ainda assim, desde que você tente consultar por ID o máximo possível, você deve ficar bem aqui. Muitas pessoas esquecem o cache L1 e pesquisam repetidamente a mesma entidade várias vezes além de seu ID (ou seja, um campo de pesquisa). Se você precisar fazer isso, salve o ID ou até a entidade inteira para pesquisas futuras.

    Há também um cache de nível 2 ("cache de consulta"). O NHibernate possui esse recurso embutido. O Linq to SQL e o Entity Framework compilaram consultas , o que pode ajudar a reduzir bastante as cargas do servidor de aplicativos compilando a própria expressão de consulta, mas não armazena em cache os dados. A Microsoft parece considerar isso uma preocupação de aplicativo e não de acesso a dados, e esse é um grande ponto fraco do L2S e do EF. Escusado será dizer que também é um ponto fraco do SQL "bruto". Para obter um desempenho realmente bom com basicamente qualquer ORM que não seja o NHibernate, você precisa implementar sua própria fachada de cache.

    Há também uma "extensão" de cache L2 para EF4, que é boa , mas não é realmente uma substituição por atacado de um cache no nível do aplicativo.

  4. Número de consultas

    Bancos de dados relacionais são baseados em conjuntos de dados. Eles são realmente bons em produzir grandes quantidades de dados em um curto período de tempo, mas não são tão bons em termos de latência de consultas, porque há uma certa quantidade de sobrecarga envolvida em todos os comandos. Um aplicativo bem projetado deve aproveitar os pontos fortes deste DBMS e tentar minimizar o número de consultas e maximizar a quantidade de dados em cada uma.

    Agora não estou dizendo para consultar o banco de dados inteiro quando você só precisa de uma linha. O que estou dizendo é que, se você precisa de Customer, Address, Phone, CreditCard, e Orderlinhas, tudo ao mesmo tempo, a fim de servir uma única página, então você deve perguntar para todos eles ao mesmo tempo, não execute cada consulta separadamente. Às vezes é pior do que isso, você verá o código que consulta o mesmo Customerregistro 5 vezes seguidas, primeiro para obter o Id, então o Name, então o EmailAddress, então ... é ridiculamente ineficiente.

    Mesmo se você precisar executar várias consultas que funcionem em conjuntos de dados completamente diferentes, geralmente é ainda mais eficiente enviar tudo para o banco de dados como um único "script" e retornar vários conjuntos de resultados. Você está preocupado com a sobrecarga, não com a quantidade total de dados.

    Isso pode parecer senso comum, mas geralmente é muito fácil perder o controle de todas as consultas que estão sendo executadas em várias partes do aplicativo; seu provedor de associação consulta as tabelas de usuário / função, sua ação de cabeçalho consulta o carrinho de compras, sua ação de menu consulta a tabela de mapas do site, sua ação da barra lateral consulta a lista de produtos em destaque e, talvez, sua página seja dividida em algumas áreas autônomas consulte as tabelas Histórico do pedido, Exibido recentemente, Categoria e Inventário separadamente e, antes que você perceba, execute 20 consultas antes mesmo de começar a exibir a página. Isso simplesmente destrói o desempenho.

    Algumas estruturas - e eu estou pensando principalmente no NHibernate aqui - são incrivelmente inteligentes sobre isso e permitem que você use algo chamado futuros que agrupam consultas inteiras e tentam executá-las todas de uma só vez, no último minuto possível. AFAIK, você está por conta própria se quiser fazer isso com qualquer uma das tecnologias da Microsoft; você precisa integrá-lo à lógica do aplicativo.

  5. Indexação, Predicados e Projeções

    Pelo menos 50% dos desenvolvedores com quem falo e até alguns DBAs parecem ter problemas com o conceito de cobertura de índices. Eles pensam: "bem, a Customer.Namecoluna está indexada, então todas as pesquisas que faço no nome devem ser rápidas". Só que não funciona dessa maneira, a menos que o Nameíndice cubra a coluna específica que você está procurando. No SQL Server, isso é feito INCLUDEna CREATE INDEXdeclaração.

    Se você ingenuamente usar em SELECT *qualquer lugar - e isso é mais ou menos o que todo ORM fará, a menos que você especifique explicitamente o contrário, usando uma projeção -, o DBMS poderá muito bem optar por ignorar completamente seus índices porque eles contêm colunas não cobertas. Uma projeção significa que, por exemplo, em vez de fazer isso:

    from c in db.Customers where c.Name == "John Doe" select c
    

    Você faz isso:

    from c in db.Customers where c.Name == "John Doe"
    select new { c.Id, c.Name }
    

    E esta vontade, para a maioria ORMs modernos, instruí-lo apenas para ir e consultar os Ide Namecolunas que são presumivelmente abrangidos pelo índice (mas não o Email, LastActivityDateou qualquer outra colunas que aconteceu para ficar lá).

    Também é muito fácil eliminar completamente quaisquer benefícios de indexação usando predicados inadequados. Por exemplo:

    from c in db.Customers where c.Name.Contains("Doe")
    

    ... parece quase idêntico à nossa consulta anterior, mas na verdade resultará em uma tabela completa ou uma varredura de índice, pois é convertida em LIKE '%Doe%'. Da mesma forma, outra consulta que parece suspeitamente simples é:

    from c in db.Customers where (maxDate == null) || (c.BirthDate >= maxDate)
    

    Supondo que você tenha um índice BirthDate, esse predicado tem uma boa chance de torná-lo completamente inútil. Nosso programador hipotético aqui obviamente tentou criar um tipo de consulta dinâmica ("apenas filtre a data de nascimento se esse parâmetro foi especificado"), mas esse não é o caminho certo para fazê-lo. Escrito assim:

    from c in db.Customers where c.BirthDate >= (maxDate ?? DateTime.MinValue)
    

    ... agora o mecanismo de banco de dados sabe como parametrizar isso e fazer uma busca de índice. Uma pequena mudança, aparentemente insignificante, na expressão da consulta pode afetar drasticamente o desempenho.

    Infelizmente, o LINQ em geral facilita muito a gravação de consultas ruins como essa, porque às vezes os provedores conseguem adivinhar o que você estava tentando fazer e otimizar a consulta, e às vezes não. Então, você acaba com resultados frustrantemente inconsistentes, que teriam sido óbvios (para um DBA experiente, de qualquer maneira) se você tivesse escrito SQL simples e antigo.

    Basicamente, tudo se resume ao fato de que você realmente precisa ficar de olho no SQL gerado e nos planos de execução que eles levam, e se você não estiver obtendo os resultados esperados, não tenha medo de ignorar o Camada ORM de vez em quando e codifique manualmente o SQL. Isso vale para qualquer ORM, não apenas para a EF.

  6. Transações e Bloqueio

    Você precisa exibir dados atualizados até o milissegundo? Talvez - depende - mas provavelmente não. Infelizmente, o Entity Framework não fornecenolock , você pode usar apenas READ UNCOMMITTEDno nível da transação (não no nível da tabela). De fato, nenhum dos ORMs é particularmente confiável sobre isso; se você quiser fazer leituras sujas, precisará descer para o nível SQL e escrever consultas ad-hoc ou procedimentos armazenados. Então, o que se resume, novamente, é como é fácil fazer isso dentro da estrutura.

    O Entity Framework percorreu um longo caminho a esse respeito - a versão 1 do EF (no .NET 3.5) foi horrível, tornou incrivelmente difícil romper a abstração de "entidades", mas agora você tem ExecuteStoreQuery e Translate , por isso é realmente não é tão ruim. Faça amizade com esses caras porque você os usará bastante.

    Há também o problema de bloqueio de gravação e deadlocks e a prática geral de reter bloqueios no banco de dados pelo menor tempo possível. Nesse sentido, a maioria dos ORMs (incluindo o Entity Framework) na verdade tendem a ser melhores que o SQL bruto, porque encapsulam o padrão da unidade de trabalho , que no EF é SaveChanges . Em outras palavras, você pode "inserir" ou "atualizar" ou "excluir" entidades no conteúdo do seu coração, sempre que quiser, seguro de que nenhuma alteração será realmente enviada ao banco de dados até que você confirme a unidade de trabalho.

    Observe que um UOW não é análogo a uma transação de longa execução. O UOW ainda usa os recursos de simultaneidade otimistas do ORM e rastreia todas as alterações na memória . Nenhuma única instrução DML é emitida até a confirmação final. Isso mantém os tempos de transação o mais baixo possível. Se você criar seu aplicativo usando SQL bruto, é muito difícil obter esse comportamento adiado.

    O que isso significa para a EF especificamente: Torne suas unidades de trabalho o mais grosseiras possível e não as comprometa até que seja absolutamente necessário. Faça isso e você terá uma contenção de bloqueio muito menor do que usaria comandos individuais do ADO.NET em momentos aleatórios.

Em conclusão:

A EF é excelente para aplicativos de alto tráfego / alto desempenho, assim como qualquer outra estrutura é adequada para aplicativos de alto tráfego / alto desempenho. O que importa é como você o usa. Aqui está uma rápida comparação das estruturas mais populares e quais recursos eles oferecem em termos de desempenho (legenda: N = Não suportado, P = Parcial, Y = sim / suportado):

                                | L2S | EF1 | EF4 | NH3 | ADO
                                +-----+-----+-----+-----+-----
Lazy Loading (entities)         |  N  |  N  |  N  |  Y  |  N
Lazy Loading (relationships)    |  Y  |  Y  |  Y  |  Y  |  N
Eager Loading (global)          |  N  |  N  |  N  |  Y  |  N
Eager Loading (per-session)     |  Y  |  N  |  N  |  Y  |  N
Eager Loading (per-query)       |  N  |  Y  |  Y  |  Y  |  Y
Level 1 (Identity) Cache        |  Y  |  Y  |  Y  |  Y  |  N
Level 2 (Query) Cache           |  N  |  N  |  P  |  Y  |  N
Compiled Queries                |  Y  |  P  |  Y  |  N  | N/A
Multi-Queries                   |  N  |  N  |  N  |  Y  |  Y
Multiple Result Sets            |  Y  |  N  |  P  |  Y  |  Y
Futures                         |  N  |  N  |  N  |  Y  |  N
Explicit Locking (per-table)    |  N  |  N  |  N  |  P  |  Y
Transaction Isolation Level     |  Y  |  Y  |  Y  |  Y  |  Y
Ad-Hoc Queries                  |  Y  |  P  |  Y  |  Y  |  Y
Stored Procedures               |  Y  |  P  |  Y  |  Y  |  Y
Unit of Work                    |  Y  |  Y  |  Y  |  Y  |  N

Como você pode ver, o EF4 (a versão atual) não se sai muito mal, mas provavelmente não é o melhor se o desempenho for sua principal preocupação. O NHibernate é muito mais maduro nessa área e até o Linq to SQL fornece alguns recursos de aprimoramento de desempenho que o EF ainda não fornece. O ADO.NET bruto geralmente é mais rápido em cenários de acesso a dados muito específicos , mas, quando você reúne todas as partes, ele realmente não oferece muitos benefícios importantes que você obtém das várias estruturas.

E, apenas para ter certeza absoluta de que pareço um registro quebrado, nada disso importa se você não criar suas estratégias de banco de dados, aplicativo e acesso a dados corretamente. Todos os itens no gráfico acima são para melhorar o desempenho além da linha de base; Na maioria das vezes, a linha de base é o que precisa de mais aprimoramentos.

Aaronaught
fonte
38
Que resposta impressionante e abrangente!
2
+1 (mais se eu pudesse) - uma das melhores respostas que já vi há algum tempo aqui e aprendi uma coisa ou duas - obrigado por compartilhar isso!
BrokenGlass
1
Esta é uma ótima resposta, mesmo que eu não concorde com tudo o que foi mencionado. A tabela que compara ORMs nem sempre está correta. O que é carregamento lento de entidades? Você quer dizer colunas carregadas preguiçosamente? Isso é suportado no L2S. Por que você acha que o NH não suporta consultas compiladas? Acho que consultas HQL nomeadas podem ser pré-compiladas. O EF4 não tem suporte para vários conjuntos de resultados.
Ladislav Mrnka
11
Eu tenho que discordar totalmente da afirmação não qualificada "EF está completamente bem para aplicativos de alto tráfego / alto desempenho", vimos repetidamente que esse não é o caso. É verdade que talvez discordemos sobre o que significa "alto desempenho", mas, por exemplo, otimizar páginas da Web em até 500 ms e gastar mais de 400 ms inexplicavelmente dentro da estrutura (e apenas 10 ms na verdade atingindo o SQL) não é "bom" para algumas situações, é absolutamente inaceitável para nossa equipe de desenvolvimento.
Nick Craver
1
Nota simples sobre futuros na EF. Eles não são fornecidos oficialmente pela equipe do MS EF, mas podem ser alcançados por meio de projetos de terceiros que definem as extensões Future <> para IQueryable <>. Por exemplo, EntityFramework.Extended by LoreSoft, disponível no NuGet. Meus testes pessoais em aplicativos de produção mostram um ganho de desempenho de até 10x ao compilar dezenas de consultas não dependentes (todas as consultas podem ser executadas em paralelo, ninguém exige o resultado de uma consulta anterior) em um único lote usando Future. Além disso, o AsNoTracking () melhora muito o desempenho ao ler muitos registros, sem atualização posterior.
David Oliván Ubieto 26/03
38

Edit: Com base na ótima resposta da @Aaronaught, estou adicionando alguns pontos visando o desempenho com a EF. Esses novos pontos são prefixados por Edit.


A maior melhoria no desempenho em sites de alto tráfego é alcançada pelo armazenamento em cache (= primeiro evitando qualquer processamento do servidor da web ou consulta ao banco de dados), seguido de processamento assíncrono para evitar o bloqueio de encadeamentos enquanto as consultas ao banco de dados são executadas.

Não há resposta à prova de balas para sua pergunta, pois ela sempre depende dos requisitos de aplicação e da complexidade das consultas. A verdade é que a produtividade do desenvolvedor com a EF esconde a complexidade por trás da qual, em muitos casos, leva ao uso incorreto da EF e a um desempenho terrível. A idéia de que você pode expor uma interface abstrata de alto nível para acesso a dados e funcionará sem problemas em todos os casos não funciona. Mesmo com o ORM, você deve saber o que está acontecendo por trás da abstração e como usá-la corretamente.

Se você não possui experiência anterior com a EF, encontrará muitos desafios ao lidar com o desempenho. Você pode cometer muito mais erros ao trabalhar com a EF em comparação com o ADO.NET. Também há muito processamento adicional no EF; portanto, o EF sempre será significativamente mais lento que o ADO.NET nativo - isso é algo que você pode medir com uma simples prova de aplicação de conceito.

Se você deseja obter o melhor desempenho da EF, provavelmente precisará:

  • Revise com muito cuidado seu acesso a dados com o SQL Profiler e revise suas consultas LINQ se elas usarem corretamente o Linq-to-entity em vez de Linq-to-objects
  • Use com muito cuidado os recursos avançados de otimização EF, como MergeOption.NoTracking
  • Use ESQL em alguns casos
  • Pré-compilar consultas que são executadas frequentemente
  • Pense em aproveitar o wrapper EF Caching para obter o "cache de segundo nível" como recurso para algumas consultas
  • Use visualizações SQL ou consultas SQL mapeadas personalizadas (requer manutenção manual do arquivo EDMX) em alguns cenários para projeções ou agregações frequentemente usadas que precisam de aprimoramentos de desempenho
  • Use SQL nativo e procedimentos armazenados para algumas consultas que não fornecem desempenho suficiente quando definidas no Linq ou ESQL
  • Editar: use cuidadosamente as consultas - todas as consultas fazem uma ida e volta separada para o banco de dados. O EFv4 não possui um lote de consultas porque não pode usar vários conjuntos de resultados por comando de banco de dados executado. O EFv4.5 suportará vários conjuntos de resultados para procedimentos armazenados mapeados.
  • Editar: Trabalhe com cuidado com modificações de dados. Novamente, a EF não possui lotes de comandos . Portanto, no ADO.NET você pode usar uma única SqlCommandinserção, atualização ou exclusão múltipla, mas com o EF, todos os comandos serão executados em uma ida e volta ao banco de dados.
  • Editar: trabalhe cuidadosamente com o mapa de identidade / cache de identidade. O EF possui um método especial ( GetByKeyna API ObjectContext ou Findna API DbContext) para consultar o cache primeiro. Se você usar o Linq-to-entity ou ESQL, ele criará uma ida e volta ao banco de dados e depois retornará a instância existente do cache.
  • Editar: Use com cuidado o carregamento ansioso. Nem sempre é uma solução ganha-ganha porque produz um enorme conjunto de dados . Como você pode ver, é muita complexidade adicional e esse é o ponto. O ORM simplifica o mapeamento e a materialização, mas ao lidar com o desempenho, ele fica muito mais complexo e você precisa fazer trocas.

Não tenho certeza se o SO ainda está usando o L2S. Eles desenvolveram um novo ORM de código aberto chamado Dapper e acho que o principal ponto por trás desse desenvolvimento foi aumentar o desempenho.

Ladislav Mrnka
fonte
Ladislav, essa é uma resposta realmente útil. É a primeira vez que ouço sobre o Dapper (e consequentemente descobri o PetaPoco, Massive) - e parece uma ideia interessante.
1
SO parece usar uma combinação de LINQ to SQL e Dapper agora: samsaffron.com/archive/2011/03/30/… Quote: "Estamos usando nosso novo ORM [Dapper] para um problema específico: mapeando SQL parametrizado para objetos de negócios Não estamos usando-o como um ORM completo. Ele não faz relacionamentos e outros sinos e assobios. Isso nos permite continuar usando o LINQ-2-SQL, onde o desempenho não importa e portar todo o nosso SQL interno para usar nosso mapeador, já que é mais rápido e flexível ".
5
@ Sluma, bem, isso é uma afirmação de meses atrás, em geral, todo o novo trabalho sobre SO é feito no Dapper, por exemplo, uma nova tabela que eu adicionei hoje nem está no arquivo dbml.
Sam Saffron
1
@ Sam: Existe uma nova postagem no blog sobre a atual estratégia de acesso a dados no SO? Seria muito interessante! Enquanto isso, o Dapper foi estendido? Meu entendimento era que Dapper não é um ORM completa, sem suporte de relacionamentos - e que sobre as atualizações, inserções, exclusões, transações, controle de alterações, etc.