Risposte:
LINQ to SQL ti obbliga a usare il modello tabella per classe. I vantaggi dell'utilizzo di questo modello sono che è veloce e facile da implementare e richiede uno sforzo minimo per far funzionare il dominio in base a una struttura di database esistente. Per applicazioni semplici, questo è perfettamente accettabile (e spesso anche preferibile), ma per applicazioni più complesse gli sviluppatori suggeriscono spesso di utilizzare invece un modello di progettazione basato sul dominio (che è ciò che NHibernate facilita).
Il problema con il modello tabella per classe è che la struttura del database ha un'influenza diretta sulla progettazione del dominio. Ad esempio, supponiamo di avere una tabella Clienti con le seguenti colonne per contenere le informazioni sull'indirizzo principale di un cliente:
Supponiamo ora che tu voglia aggiungere colonne anche per l'indirizzo postale del cliente in modo da aggiungere le seguenti colonne alla tabella Clienti:
Utilizzando LINQ to SQL, l'oggetto Customer nel tuo dominio ora avrebbe proprietà per ciascuna di queste otto colonne. Ma se stavi seguendo un modello di progettazione basato sul dominio, probabilmente avresti creato una classe Indirizzo e la tua classe Cliente avrebbe avuto due proprietà Indirizzo, una per l'indirizzo postale e una per l'indirizzo corrente.
Questo è un semplice esempio, ma dimostra come il modello tabella per classe può portare a un dominio un po 'maleodorante. Alla fine, tocca a te. Ancora una volta, per app semplici che necessitano solo della funzionalità CRUD (creazione, lettura, aggiornamento, eliminazione) di base, LINQ to SQL è l'ideale per la semplicità. Ma personalmente mi piace usare NHibernate perché facilita un dominio più pulito.
Modifica: @lomaxx - Sì, l'esempio che ho usato era semplicistico e avrebbe potuto essere ottimizzato per funzionare bene con LINQ to SQL. Volevo mantenerlo il più semplice possibile per portare a casa il punto. Tuttavia, resta il punto che esistono diversi scenari in cui avere la struttura del database per determinare la struttura del dominio sarebbe una cattiva idea, o almeno porterebbe a una progettazione OO non ottimale.
Due punti che sono stati persi finora:
LINQ to SQL non funziona con Oracle o con qualsiasi database diverso da SqlServer. Tuttavia, le terze parti offrono un supporto migliore per Oracle, ad esempio dotConnect di devArt , DbLinq , Mindscape's LightSpeed e ALinq . (Non ho alcuna esperienza personale con questi)
Da Linq a NHibernate puoi usare Linq con un Nhiberate, quindi potrebbe rimuovere un motivo per non usarlo.
Anche la nuova interfaccia fluente a Nhibernate sembra rendere meno doloroso configurare la mappatura di Nhibernate. (Eliminando uno dei punti dolenti di Nhibernate)
Aggiornare
Linq to Nhiberate è migliore in Nhiberate v3 che ora è in alpha . Sembra che Nhiberate v3 possa essere spedito verso la fine di quest'anno.
Anche Entity Frame Work a partire da .net 4 sta iniziando a sembrare un'opzione reale.
@ Kevin: Penso che il problema con l'esempio che stai presentando sia che stai usando un design di database scadente. Avrei pensato che avresti creato una tabella clienti e una tabella indirizzi e normalizzato le tabelle. Se lo fai, puoi sicuramente utilizzare Linq To SQL per lo scenario che stai suggerendo. Scott Guthrie ha una grande serie di post sull'uso di Linq To SQL che ti consiglio vivamente di dare un'occhiata.
Non penso che si possa dire che Linq e NHibernate si completano a vicenda in quanto ciò implicherebbe che potrebbero essere usati insieme, e sebbene questo sia possibile, è molto meglio sceglierne uno e attenersi ad esso.
NHibernate ti consente di mappare le tabelle del database agli oggetti del tuo dominio in modo altamente flessibile. Consente inoltre di utilizzare HBL per interrogare il database.
Linq to SQL ti consente anche di mappare gli oggetti del tuo dominio al database, tuttavia utilizza la sintassi delle query Linq per interrogare il database
La differenza principale qui è che la sintassi delle query Linq viene controllata in fase di compilazione dal compilatore per garantire che le query siano valide.
Alcune cose da tenere presente con linq è che è disponibile solo in .net 3.x ed è supportato solo in VS2008. NHibernate è disponibile in 2.0 e 3.x così come VS2005.
Alcune cose da tenere presente con NHibernate è che non genera i tuoi oggetti di dominio, né genera i file di mappatura. Devi farlo manualmente. Linq può
farlo automaticamente per te.
Fluent NHibernate può generare i file di mappatura in base a semplici convenzioni. Nessuna scrittura XML e fortemente tipizzata.
Di recente ho lavorato a un progetto in cui dovevamo passare da Linq a SQL a NHibernate per motivi di prestazioni. Soprattutto il modo in cui L2S materializza gli oggetti sembra più lento di quello di NHibernate e anche la gestione del cambiamento è piuttosto lenta. E può essere difficile disattivare la gestione delle modifiche per scenari specifici in cui non è necessaria.
Se intendi utilizzare le tue entità disconnesse da DataContext, ad esempio negli scenari WCF, potresti avere molti problemi a connetterle nuovamente a DataContext per aggiornare le modifiche. Non ho avuto problemi con NHibernate.
La cosa che mi mancherà da L2S è principalmente la generazione di codice che mantiene le relazioni aggiornate su entrambe le estremità delle entità. Ma immagino che ci siano alcuni strumenti per NHibernate per farlo anche là fuori ...
.ObjectTrackingEnabled = false
sul tuo DataContext
avresti risolto il tuo problema di rilevamento delle modifiche. Fintanto che si accetta il modello di unità di lavoro e non si cerca di fare DDD, Linq-to-SQL offre davvero.
Puoi chiarire cosa intendi per "LINQ"?
LINQ non è una tecnologia di accesso ai dati, è solo una funzionalità del linguaggio che supporta l'esecuzione di query come costrutto nativo. Può interrogare qualsiasi modello a oggetti che supporti interfacce specifiche (ad esempio IQueryable).
Molte persone si riferiscono a LINQ To SQL come LINQ, ma non è affatto corretto. Microsoft ha appena rilasciato LINQ To Entities con .NET 3.5 SP1. Inoltre, NHibernate ha un'interfaccia LINQ, quindi puoi usare LINQ e NHibernate per ottenere i tuoi dati.
Con LINQ, presumo che tu intenda LINQ to SQL perché LINQ, di per sé, non ha alcun database associato ad esso. È solo un linguaggio di query che ha un carico di barca di zucchero sintetico per farlo sembrare SQL-ish.
Negli esempi di base di base, NHibernate e LINQ to SQL sembrano risolvere entrambi lo stesso problema. Una volta ottenuto il superamento, ti renderai presto conto che NHibernate supporta molte funzionalità che ti consentono di creare modelli di dominio davvero ricchi. Esiste anche un progetto LINQ to NHibernate che consente di utilizzare LINQ per eseguire query su NHibernate più o meno allo stesso modo in cui utilizzeresti LINQ to SQL.
Per prima cosa separiamo due cose diverse: la modellazione di database si occupa dei dati mentre la modellazione di oggetti si occupa di entità e relazioni.
Il vantaggio di Linq-to-SQL consiste nel generare rapidamente classi dallo schema del database in modo che possano essere utilizzate come oggetti record attivi (vedere la definizione del modello di progettazione del record attivo).
Il vantaggio di NHibernate consiste nel consentire flessibilità tra la modellazione degli oggetti e la modellazione del database. Il database può essere modellato per riflettere al meglio i dati, ad esempio prendendo in considerazione le prestazioni. Mentre la modellazione a oggetti rifletterà al meglio gli elementi della regola aziendale utilizzando un approccio come Domain-Driven-Design. (vedi il commento di Kevin Pang)
Con database legacy con scadenti convenzioni di modellazione e / o denominazione, Linq-to-SQL rifletterà queste strutture e nomi indesiderati alle tue classi. Tuttavia NHibernate può nascondere questo pasticcio con i mappatori di dati.
Nei progetti greenfield in cui i database hanno una buona denominazione e una bassa complessità, Linq-to-SQL può essere una buona scelta.
Tuttavia è possibile utilizzare Fluent NHibernate con le mappature automatiche per questo stesso scopo con la mappatura come convenzione. In questo caso non ti preoccupi di nessun mappatore di dati con XML o C # e lascia che NHibernate generi lo schema del database dalle tue entità in base a una convenzione che puoi personalizzare.
D'altra parte la curva di apprendimento di Linq-to-SQL è più piccola di NHibernate.
Oppure potresti usare il progetto Castle ActiveRecords. L'ho usato per un breve periodo di tempo per aumentare del nuovo codice per un progetto legacy. Usa NHibernate e funziona sul pattern di registrazione attivo (sorprendente dato il nome che conosco). Non ho provato, ma presumo che una volta che l'hai usato, se senti il bisogno di passare direttamente al supporto di NHibernate, non sarebbe troppo farlo per una parte o per tutto il tuo progetto.
Come hai scritto "per una persona che non ha utilizzato nessuno dei due", LINQ to SQL è facile da usare, quindi chiunque può usarlo facilmente Supporta anche le procedure, il che aiuta la maggior parte del tempo. Supponi di voler ottenere dati da più di una tabella, quindi scrivi una procedura e trascina quella procedura nel designer e creerà tutto per te, Supponiamo che il nome della tua procedura sia "CUSTOMER_ORDER_LINEITEM" che recupera il record da tutte queste tre tabelle quindi scrivi semplicemente
MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();
puoi anche usare il tuo oggetto record nel ciclo foreach, che non è supportato da NHibernate