Respostas:
LINQ to SQL força você a usar o padrão tabela por classe. Os benefícios de usar esse padrão são que ele é rápido e fácil de implementar e exige muito pouco esforço para colocar seu domínio em execução com base em uma estrutura de banco de dados existente. Para aplicativos simples, isso é perfeitamente aceitável (e muitas vezes até preferível), mas para aplicativos mais complexos, os desenvolvedores geralmente sugerem o uso de um padrão de design orientado por domínio (que é o que o NHibernate facilita).
O problema com o padrão tabela por classe é que a estrutura do banco de dados tem uma influência direta sobre o design do domínio. Por exemplo, digamos que você tenha uma tabela Clientes com as seguintes colunas para conter as informações do endereço principal de um cliente:
Agora, digamos que você também queira adicionar colunas para o endereço de correspondência do cliente, então adicione as seguintes colunas à tabela Clientes:
Usando LINQ to SQL, o objeto Customer em seu domínio agora teria propriedades para cada uma dessas oito colunas. Mas se você estivesse seguindo um padrão de design orientado por domínio, provavelmente teria criado uma classe Address e sua classe Customer manteria duas propriedades Address, uma para o endereço de correspondência e outra para o endereço atual.
Esse é um exemplo simples, mas demonstra como o padrão tabela por classe pode levar a um domínio um tanto fedorento. No final, depende de você. Novamente, para aplicativos simples que precisam apenas da funcionalidade CRUD (criar, ler, atualizar, excluir) básica, o LINQ to SQL é ideal por causa da simplicidade. Mas pessoalmente gosto de usar o NHibernate porque facilita um domínio mais limpo.
Edit: @lomaxx - Sim, o exemplo que usei era simplista e poderia ter sido otimizado para funcionar bem com LINQ to SQL. Eu queria mantê-lo o mais básico possível para esclarecer o ponto. A questão permanece, porém, que existem vários cenários em que ter sua estrutura de banco de dados determinando sua estrutura de domínio seria uma má ideia, ou pelo menos levaria a um projeto OO abaixo do ideal.
Dois pontos que foram perdidos até agora:
LINQ to SQL não funciona com Oracle ou qualquer banco de dados além do SqlServer. No entanto, terceiros oferecem melhor suporte para Oracle, por exemplo, devArt's dotConnect , DbLinq , Mindscape's LightSpeed e ALinq . (Não tenho nenhuma experiência pessoal com estes)
O Linq para NHibernate permite que você use o Linq com um Nhiberate, portanto, pode haver um motivo para não usar.
Além disso, a nova interface fluente do Nhibernate parece tornar menos doloroso configurar o mapeamento do Nhibernate. (Removendo um dos pontos fracos do Nhibernate)
Atualizar
Linq para Nhiberate é melhor no Nhiberate v3 que agora está em alfa . Parece que o Nhiberate v3 pode ser lançado no final deste ano.
O Entity Frame Work a partir do .net 4 também está começando a parecer uma opção real.
@ Kevin: Acho que o problema com o exemplo que você está apresentando é que você está usando um design de banco de dados ruim. Eu pensei que você criaria uma tabela de clientes e uma tabela de endereços e normalizaria as tabelas. Se você fizer isso, poderá usar definitivamente o Linq To SQL para o cenário que está sugerindo. Scott Guthrie tem uma ótima série de posts sobre como usar o Linq To SQL que eu sugiro fortemente que você dê uma olhada.
Eu não acho que você poderia dizer que Linq e NHibernate se complementam, já que isso implicaria que eles poderiam ser usados juntos e, embora isso seja possível, é muito melhor escolher um e mantê-lo.
NHibernate permite mapear suas tabelas de banco de dados para seus objetos de domínio de uma forma altamente flexível. Ele também permite que você use o HBL para consultar o banco de dados.
Linq para SQL também permite que você mapeie seus objetos de domínio para o banco de dados, no entanto, ele usa a sintaxe de consulta Linq para consultar o banco de dados
A principal diferença aqui é que a sintaxe da consulta Linq é verificada no tempo de compilação pelo compilador para garantir que suas consultas sejam válidas.
Algumas coisas a serem observadas com o linq é que ele está disponível apenas em .net 3.xe é compatível apenas com o VS2008. NHibernate está disponível em 2.0 e 3.x, bem como em VS2005.
Algumas coisas a serem observadas com o NHibernate é que ele não gera seus objetos de domínio, nem gera os arquivos de mapeamento. Você precisa fazer isso manualmente. O Linq pode
fazer isso automaticamente para você.
O Fluent NHibernate pode gerar seus arquivos de mapeamento com base em convenções simples. Sem gravação de XML e fortemente tipado.
Recentemente, trabalhei em um projeto em que precisávamos mudar de Linq para SQL para NHibernate por motivos de desempenho. Especialmente a maneira do L2S de materializar os objetos parece mais lenta do que a idem do NHibernate e o gerenciamento de mudanças também é bastante lento. E pode ser difícil desativar o gerenciamento de mudanças em cenários específicos onde ele não é necessário.
Se você for usar suas entidades desconectadas do DataContext - em cenários WCF, por exemplo - você pode ter muitos problemas para conectá-las ao DataContext novamente para atualizar as alterações. Não tive problemas com isso com o NHibernate.
O que vou sentir falta do L2S é principalmente a geração de código que mantém as relações atualizadas em ambas as extremidades das entidades. Mas acho que existem algumas ferramentas para o NHibernate fazer isso por aí também ...
.ObjectTrackingEnabled = false
você DataContext
teria resolvido o problema de rastreamento de alterações. Contanto que você adote o padrão de unidade de trabalho e não esteja procurando fazer DDD, o Linq-to-SQL realmente cumpre.
Você pode esclarecer o que quer dizer com "LINQ"?
LINQ não é uma tecnologia de acesso a dados, é apenas um recurso de linguagem que oferece suporte a consultas como uma construção nativa. Ele pode consultar qualquer modelo de objeto que suporte interfaces específicas (por exemplo, IQueryable).
Muitas pessoas se referem a LINQ To SQL como LINQ, mas isso não é correto. A Microsoft acaba de lançar o LINQ To Entities com .NET 3.5 SP1. Além disso, o NHibernate tem uma interface LINQ, então você pode usar o LINQ e o NHibernate para obter seus dados.
Por LINQ, estou supondo que você quer dizer LINQ to SQL porque o LINQ, por si só, não tem nenhum banco de dados "em andamento" associado a ele. É apenas uma linguagem de consulta que tem um monte de açúcar syntac para fazer com que pareça SQL.
No básico dos exemplos básicos, NHibernate e LINQ to SQL parecem estar resolvendo o mesmo problema. Depois de passar, você logo percebe que o NHibernate tem suporte para muitos recursos que permitem criar modelos de domínio verdadeiramente ricos. Há também um projeto LINQ to NHibernate que permite usar LINQ para consultar o NHibernate da mesma forma que você usaria LINQ to SQL.
Primeiro, vamos separar duas coisas diferentes: a modelagem de banco de dados se preocupa com os dados, enquanto a modelagem de objetos se preocupa com entidades e relacionamentos.
A vantagem do Linq para SQL é gerar rapidamente classes fora do esquema do banco de dados para que possam ser usadas como objetos de registro ativo (consulte a definição do padrão de design do registro ativo).
A vantagem do NHibernate é permitir flexibilidade entre a modelagem de objetos e a modelagem de banco de dados. O banco de dados pode ser modelado para melhor refletir seus dados, levando em consideração o desempenho, por exemplo. Embora sua modelagem de objetos reflita melhor os elementos da regra de negócios usando uma abordagem como Domain-Driven-Design. (veja o comentário de Kevin Pang)
Com bancos de dados legados com modelagem pobre e / ou convenções de nomenclatura, o Linq-to-SQL refletirá essas estruturas e nomes indesejados para suas classes. No entanto, o NHibernate pode esconder essa bagunça com mapeadores de dados.
Em projetos novos em que os bancos de dados têm boa nomenclatura e baixa complexidade, o Linq-to-SQL pode ser uma boa escolha.
No entanto, você pode usar o Fluent NHibernate com mapeamentos automáticos para o mesmo propósito com o mapeamento por convenção. Neste caso, você não se preocupa com nenhum mapeador de dados com XML ou C # e deixe o NHibernate gerar o esquema do banco de dados de suas entidades com base em uma convenção que você pode personalizar.
Por outro lado, a curva de aprendizado do Linq-to-SQL é menor que o NHibernate.
Ou você pode usar o projeto Castle ActiveRecords. Estou usando isso há um curto período de tempo para desenvolver um novo código para um projeto legado. Ele usa NHibernate e funciona no padrão de registro ativo (surpreendente dado o nome que eu conheço). Eu não tentei, mas suponho que uma vez que você o tenha usado, se você sentir a necessidade de recorrer diretamente ao suporte do NHibernate, não seria demais fazê-lo para parte ou todo o seu projeto.
Como você escreveu "para uma pessoa que não usou nenhum deles", o LINQ to SQL é fácil de usar, então qualquer um pode usá-lo facilmente. Ele também oferece suporte a procedimentos, o que ajuda na maioria das vezes. Suponha que você queira obter dados de mais de uma tabela, em seguida, escreva um procedimento e arraste esse procedimento para o designer e ele criará tudo para você. Suponha que o nome do seu procedimento seja "CUSTOMER_ORDER_LINEITEM", que busca o registro de todas essas três tabelas e, em seguida, basta escrever
MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();
você pode usar o objeto de registros no loop foreach também, que não é suportado pelo NHibernate