Réponses:
LINQ to SQL vous oblige à utiliser le modèle table par classe. Les avantages de l'utilisation de ce modèle sont qu'il est rapide et facile à mettre en œuvre et qu'il ne faut que très peu d'efforts pour faire fonctionner votre domaine sur la base d'une structure de base de données existante. Pour les applications simples, c'est parfaitement acceptable (et souvent même préférable), mais pour les applications plus complexes, les développeurs suggéreront souvent d'utiliser une conception axée sur le domaine. modèle de la place (ce que NHibernate facilite).
Le problème avec le modèle table par classe est que la structure de votre base de données a une influence directe sur la conception de votre domaine. Par exemple, supposons que vous ayez une table Clients avec les colonnes suivantes pour contenir les informations d'adresse principale d'un client:
Maintenant, supposons que vous souhaitiez également ajouter des colonnes pour l'adresse postale du client afin d'ajouter les colonnes suivantes à la table Clients:
En utilisant LINQ to SQL, l'objet Customer de votre domaine aurait désormais des propriétés pour chacune de ces huit colonnes. Mais si vous suiviez un modèle de conception piloté par domaine, vous auriez probablement créé une classe Address et votre classe Customer détenait deux propriétés Address, une pour l'adresse postale et une pour leur adresse actuelle.
C'est un exemple simple, mais il montre comment le modèle table par classe peut conduire à un domaine un peu malodorant. En fin de compte, c'est à vous. Encore une fois, pour les applications simples qui n'ont besoin que de la fonctionnalité CRUD de base (créer, lire, mettre à jour, supprimer), LINQ to SQL est idéal en raison de sa simplicité. Mais personnellement, j'aime utiliser NHibernate car il facilite un domaine plus propre.
Edit: @lomaxx - Oui, l'exemple que j'ai utilisé était simpliste et aurait pu être optimisé pour bien fonctionner avec LINQ to SQL. Je voulais le garder aussi basique que possible pour faire ressortir le point. Il n'en reste pas moins qu'il existe plusieurs scénarios dans lesquels le fait de déterminer la structure de votre domaine par la structure de votre base de données serait une mauvaise idée, ou au moins conduirait à une conception OO sous-optimale.
Deux points qui ont été manqués jusqu'à présent:
LINQ to SQL ne fonctionne pas avec Oracle ou toute autre base de données en dehors de SqlServer. Cependant 3e parties ne offrent un meilleur soutien pour Oracle, par exemple dotConnect de DevArt , DbLinq , LightSpeed de Mindscape et ALinq . (Je n'ai aucune expérience personnelle avec ces derniers)
Linq to NHibernate vous permet d'utiliser Linq avec un Nhiberate, il peut donc supprimer une raison de ne pas l'utiliser.
De plus, la nouvelle interface fluide de Nhibernate semble rendre la configuration de la cartographie de Nhibernate moins compliquée. (Suppression de l'un des points douloureux de Nhibernate)
Mettre à jour
Linq to Nhiberate est meilleur dans Nhiberate v3 qui est maintenant en alpha . On dirait que Nhiberate v3 pourrait être livré vers la fin de cette année.
L' Entity Frame Work à partir de .net 4 commence également à ressembler à une véritable option.
@Kevin: Je pense que le problème avec l'exemple que vous présentez est que vous utilisez une mauvaise conception de base de données. J'aurais pensé que vous créeriez une table client et une table d'adresses et que vous normaliseriez les tables. Si vous faites cela, vous pouvez certainement utiliser Linq To SQL pour le scénario que vous suggérez. Scott Guthrie a une grande série d'articles sur l'utilisation de Linq To SQL que je vous suggère fortement de consulter.
Je ne pense pas que vous puissiez dire que Linq et NHibernate se complètent car cela impliquerait qu'ils pourraient être utilisés ensemble, et bien que cela soit possible, vous feriez bien mieux d'en choisir un et de vous y tenir.
NHibernate vous permet de mapper vos tables de base de données à vos objets de domaine de manière très flexible. Il vous permet également d'utiliser HBL pour interroger la base de données.
Linq to SQL vous permet également de mapper vos objets de domaine à la base de données, mais il utilise la syntaxe de requête Linq pour interroger la base de données
La principale différence ici est que la syntaxe de la requête Linq est vérifiée au moment de la compilation par le compilateur pour s'assurer que vos requêtes sont valides.
Certaines choses à savoir avec linq sont qu'il n'est disponible que dans .net 3.x et n'est pris en charge que dans VS2008. NHibernate est disponible en 2.0 et 3.x ainsi qu'en VS2005.
Certaines choses à savoir avec NHibernate sont qu'il ne génère pas vos objets de domaine, ni ne génère les fichiers de mappage. Vous devez le faire manuellement. Linq peut le
faire automatiquement pour vous.
Fluent NHibernate peut générer vos fichiers de cartographie sur la base de conventions simples. Aucune écriture XML et fortement typé.
J'ai récemment travaillé sur un projet, dans lequel nous devions passer de Linq à SQL à NHibernate pour des raisons de performances. Surtout la manière de matérialiser les objets par L2S semble plus lente que celle de NHibernate et la gestion du changement est également assez lente. Et il peut être difficile de désactiver la gestion du changement pour des scénarios spécifiques où elle n'est pas nécessaire.
Si vous envisagez d'utiliser vos entités déconnectées du DataContext - dans les scénarios WCF par exemple - vous risquez de rencontrer de nombreux problèmes pour les connecter à nouveau au DataContext pour mettre à jour les modifications. Je n'ai eu aucun problème avec cela avec NHibernate.
Ce qui me manquera dans L2S, c'est surtout la génération de code qui maintient les relations à jour aux deux extrémités des entités. Mais je suppose qu'il existe des outils pour NHibernate pour le faire aussi ...
.ObjectTrackingEnabled = false
, vous DataContext
auriez résolu votre problème de suivi des modifications. Tant que vous adhérez au modèle d'unité de travail et que vous ne cherchez pas à faire du DDD, Linq-to-SQL est vraiment efficace.
Pouvez-vous clarifier ce que vous entendez par "LINQ"?
LINQ n'est pas une technologie d'accès aux données, c'est juste une fonctionnalité de langage qui prend en charge les requêtes en tant que construction native. Il peut interroger n'importe quel modèle d'objet prenant en charge des interfaces spécifiques (par exemple IQueryable).
Beaucoup de gens se réfèrent à LINQ To SQL comme LINQ, mais ce n'est pas du tout correct. Microsoft vient de publier LINQ To Entities avec .NET 3.5 SP1. De plus, NHibernate dispose d'une interface LINQ, vous pouvez donc utiliser LINQ et NHibernate pour accéder à vos données.
Par LINQ, je suppose que vous entendez LINQ to SQL parce que LINQ, par lui-même, n'a pas de base de données "en cours" qui lui est associée. C'est juste un langage de requête qui a une charge de sucre syntacique pour lui donner un aspect SQL-ish.
Dans les exemples les plus basiques, NHibernate et LINQ to SQL semblent tous deux résoudre le même problème. Une fois que vous avez réussi, vous vous rendez vite compte que NHibernate prend en charge de nombreuses fonctionnalités qui vous permettent de créer des modèles de domaine vraiment riches. Il existe également un projet LINQ to NHibernate qui vous permet d'utiliser LINQ pour interroger NHibernate de la même manière que vous utiliseriez LINQ to SQL.
Commençons par séparer deux choses différentes: la modélisation de base de données concerne les données tandis que la modélisation d'objets concerne les entités et les relations.
L'avantage de Linq-to-SQL est de générer rapidement des classes à partir du schéma de base de données afin qu'elles puissent être utilisées comme objets d'enregistrement actifs (voir la définition du modèle de conception d'enregistrement actif).
L'avantage NHibernate est de permettre une flexibilité entre votre modélisation d'objets et la modélisation de base de données. La base de données peut être modélisée pour refléter au mieux vos données en tenant compte des performances par exemple. Alors que votre modélisation d'objets reflètera le mieux les éléments de la règle métier en utilisant une approche telle que Domain-Driven-Design. (voir le commentaire de Kevin Pang)
Avec des bases de données héritées avec de mauvaises conventions de modélisation et / ou de dénomination, Linq-to-SQL reflétera ces structures et noms indésirables dans vos classes. Cependant NHibernate peut cacher ce désordre avec les mappeurs de données.
Dans les nouveaux projets où les bases de données ont une bonne dénomination et une faible complexité, Linq-to-SQL peut être un bon choix.
Cependant, vous pouvez utiliser Fluent NHibernate avec des mappages automatiques dans ce même but avec le mappage comme convention. Dans ce cas, vous ne vous souciez pas des mappeurs de données avec XML ou C # et laissez NHibernate générer le schéma de base de données à partir de vos entités selon une convention que vous pouvez personnaliser.
D'autre part, la courbe d'apprentissage de Linq-to-SQL est plus petite que NHibernate.
Ou vous pouvez utiliser le projet Castle ActiveRecords. J'utilise cela depuis peu de temps pour créer un nouveau code pour un projet hérité. Il utilise NHibernate et fonctionne sur le modèle d'enregistrement actif (surprenant étant donné son nom que je connais). Je n'ai pas essayé, mais je suppose qu'une fois que vous l'avez utilisé, si vous ressentez le besoin de passer directement au support NHibernate, ce ne serait pas trop de le faire pour tout ou partie de votre projet.
Comme vous l'avez écrit "pour une personne qui n'a utilisé aucun des deux" LINQ to SQL est facile à utiliser et tout le monde peut l'utiliser facilement. Il prend également en charge les procédures, ce qui aide la plupart du temps. Supposons que vous souhaitiez obtenir des données de plus d'une table, puis écrivez une procédure et faites glisser cette procédure vers le concepteur et elle créera tout pour vous, Supposons que le nom de votre procédure soit "CUSTOMER_ORDER_LINEITEM" qui récupère l'enregistrement de ces trois tables puis écrivez simplement
MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();
vous pouvez également utiliser votre objet records dans la boucle foreach, ce qui n'est pas pris en charge par NHibernate