117

As someone who hasn't used either technology on real-world projects I wonder if anyone knows how these two complement each other and how much their functionalities overlap?

Rex M
  • 135,205
  • 29
  • 270
  • 310
Manu
  • 27,156
  • 27
  • 70
  • 82

9 Answers9

113

LINQ to SQL forces you to use the table-per-class pattern. The benefits of using this pattern are that it's quick and easy to implement and it takes very little effort to get your domain running based on an existing database structure. For simple applications, this is perfectly acceptable (and oftentimes even preferable), but for more complex applications devs will often suggest using a domain driven design pattern instead (which is what NHibernate facilitates).

The problem with the table-per-class pattern is that your database structure has a direct influence over your domain design. For instance, let's say you have a Customers table with the following columns to hold a customer's primary address information:

  • StreetAddress
  • City
  • State
  • Zip

Now, let's say you want to add columns for the customer's mailing address as well so you add in the following columns to the Customers table:

  • MailingStreetAddress
  • MailingCity
  • MailingState
  • MailingZip

Using LINQ to SQL, the Customer object in your domain would now have properties for each of these eight columns. But if you were following a domain driven design pattern, you would probably have created an Address class and had your Customer class hold two Address properties, one for the mailing address and one for their current address.

That's a simple example, but it demonstrates how the table-per-class pattern can lead to a somewhat smelly domain. In the end, it's up to you. Again, for simple apps that just need basic CRUD (create, read, update, delete) functionality, LINQ to SQL is ideal because of simplicity. But personally I like using NHibernate because it facilitates a cleaner domain.

Edit: @lomaxx - Yes, the example I used was simplistic and could have been optimized to work well with LINQ to SQL. I wanted to keep it as basic as possible to drive home the point. The point remains though that there are several scenarios where having your database structure determine your domain structure would be a bad idea, or at least lead to suboptimal OO design.

Ryan Lundy
  • 187,365
  • 35
  • 174
  • 206
Kevin Pang
  • 39,694
  • 37
  • 117
  • 169
  • 4
    You can code the implementation your repository using Linq To SQL, it's very handy. – Nicolas Dorier May 02 '09 at 15:42
  • 1
    I think it's not ActiveRecord, even mapped classes encapsulate some of the infrastructure logic. ActiveRecord pattern would be if you could have Customer.Save(). L2S implements Unit of Work pattern with DataContext class, like Session in nHibernate, but NH has real POCO approach. – Hrvoje Hudo May 29 '09 at 08:50
  • Damn, L2S is not active record by anymeans... Active record means that object it self holds all database connectivity, with L2S this is not a case. – Mike Chaliy Nov 15 '09 at 16:50
  • Agreed, really need to do an edit to correct the ActiveRecord bit. – James H Nov 18 '09 at 08:19
  • You guys are right. What I should have said was "table-per-class", not "Active Record". Updated answer to fix that. – Kevin Pang Nov 23 '09 at 23:33
  • 1
    What about normalizing your database instead, and letting your DAL be generated by tools i.e. SQLMetal? – Alex Jul 01 '10 at 19:31
  • Ok, so what denotes a "more complicated application"? I mean I've seen several .coms use LINQ to SQL just fine and the Business Domain can have a ton of complicated scenarios/logic. So when you say complicated do you mean BL or just that the DL needs more logic in it for supporting other things such as other types of DBs or what?? What type of application denotes "complicated" vs. "not complicated". That is not clear at all. – PositiveGuy Dec 14 '10 at 05:28
  • And I don't get how your example is showing smelly. With your DDD explanation you'd still have to have 2 mail address properties in your Customer class exposing the Address instances for both types of addresses. So changing the DB table will still force you to change the Customer class by adding that column property in your Customer object in your DDD implemenation to expose a new Address instance type. – PositiveGuy Dec 14 '10 at 05:35
  • Nicolas, I don't understand your sentence. – PositiveGuy Dec 14 '10 at 05:35
  • 3
    @CoffeeAddict When the impedance mismatch is too much to bear, that's when your application is too complicated to use LINQ to SQL on, imo. The reason my example is smelly is because using LINQ to SQL would result in 8 properties as opposed to 2 and restricts your ability to do things like implement functions that take in an Address class or implement routines on the Address class that you would be able to do if you had used NHibernate. – Kevin Pang Dec 15 '10 at 22:33
  • @Kevin Thanks a lot for your example and further exaplanation via your reply. Ok so what determines an app that needs DDD and an ORM like NHibernate? I mean for example many .coms I know of or have worked for have only needed mostly basic CRUDs. I mean the domain logic can get complicated sometimes but I mean other than that, then would a .com ever need something like NHibernate? What type of app would and why? I just don't get where the line is drawn and for what attributes or examples of complex needs vs. simple where simple can even be in large .coms. – PositiveGuy Dec 23 '10 at 04:33
  • @CoffeeAddict It's subjective and I don't think there's a clear black-and-white answer. Once you get used to using NHibernate, it's not really that big of a hassle to use it in every project. However, if all you're working on is basic CRUD apps I can see the argument for not wanting to waste your time learning a new tool since the benefits will be minor. – Kevin Pang Dec 23 '10 at 16:36
  • 1
    @kevin "LINQ to SQL uses the active record pattern" That is not correct. It's like saying that ADO.NET uses active record, or NHibernate uses active record. They are all data access technologies and do not enforce any particular data access pattern. I personally like to use linq-to-sql with the repository pattern. You are correct that linq-to-sql does not support complex mappings like NHibernate does. – liammclennan May 12 '10 at 15:53
  • The thing here, as i see it, is that you are using the generated classes (linqtosql) as domain classes. I think that's a bad approach if you want a richer domain model. Your repository should be responsible for creating the domain model from your linqtosql entities. You can still have a Customer class with 2 properties for Address. All you have to do in to construct this class in your repository. – Pepito Fernandez Nov 13 '12 at 18:44
26

Two points that have been missed so far:

Also the new fluent interface to Nhibernate seems to make it less painful to configure Nhibernate’s mapping. (Removing one of the pain points of Nhibernate)


Update

Linq to Nhiberate is better in Nhiberate v3 that is now in alpha. Looks like Nhiberate v3 may ship towards the end of this year.

The Entity Frame Work as of .net 4 is also starting to look like a real option.

Ian Ringrose
  • 49,271
  • 50
  • 203
  • 302
  • 2
    Linq to NHibernate is still in a very early stage. It is not a complete implementation, and arguably, is not ready for production use at all. – liammclennan Jul 23 '09 at 04:31
  • The new LinqConnect 2.0 release introduces some additional features for convenience, like Table Per Type inheritance support, PLINQ support, and the Batch Updates functionality. ORM Designer (Devart Entity Developer) now has Model First support and Mapping Synchronization feature. More details: http://www.devart.com/news/2010/dotconnects600.html – Devart Dec 02 '10 at 15:48
23

@Kevin: I think the problem with the example you are presenting is that you are using a poor database design. I would have thought you'd create a customer table and an address table and normalized the tables. If you do that you can definately use Linq To SQL for the scenario you're suggesting. Scott Guthrie has a great series of posts on using Linq To SQL which I would strongly suggest you check out.

I don't think you could say Linq and NHibernate complement each other as that would imply that they could be used together, and whilst this is possible, you're much better off choosing one and sticking to it.

NHibernate allows you to map your database tables to your domain objects in a highly flexible way. It also allows you to use HBL to query the database.

Linq to SQL also allows you to map your domain objects to the database however it use the Linq query syntax to query the database

The main difference here is that the Linq query syntax is checked at compile time by the compiler to ensure your queries are valid.

Some things to be aware of with linq is that it's only available in .net 3.x and is only supported in VS2008. NHibernate is available in 2.0 and 3.x as well as VS2005.

Some things to be aware of with NHibernate is that it does not generate your domain objects, nor does it generate the mapping files. You need to do this manually. Linq can
do this automatically for you.

lomaxx
  • 104,787
  • 56
  • 140
  • 177
  • 15
    What if you are writing code against a legacy database structure that you can't change because it supports other apps. Do you want your domain model to inherit the poor database design or do you want to create a rich domain model that can vary independently of the database structure? – Larry Foulkrod Oct 02 '08 at 23:06
7

Fluent NHibernate can generate your mapping files based on simple conventions. No XML-writing and strongly typed.

I've recently worked on a project, where we needed to change from Linq To SQL to NHibernate for performance reasons. Especially L2S's way of materializing the objects seems slower than NHibernate's ditto and the change management is quite slow too. And it can be hard to turn the change management off for specific scenarios where it is not needed.

If you are going to use your entities disconnected from the DataContext - in WCF scenarios for example - you're may have a lot of trouble connecting them to the DataContext again for updating the changes. I have had no problems with that with NHibernate.

The thing I will miss from L2S is mostly the code generation that keeps relations up-to-date on both ends of the entities. But I guess there are some tools for NHibernate to do that out there too...

asgerhallas
  • 14,321
  • 6
  • 45
  • 61
  • 2
    Just in case others read your post and are thinking of jumping ship too - `.ObjectTrackingEnabled = false` on your `DataContext` would have solved your change tracking issue. As long as you buy into the unit-of-work pattern and aren't looking to do DDD, Linq-to-SQL really delivers. – mattmc3 Dec 14 '10 at 16:54
  • "*we needed to change from Linq To SQL to NHibernate for performance reasons*" -- Having used [Fluent, no less] NHibernate for a few years, I feel for you. I think we mostly cheated and ended up writing native SQL for real performance pressure points. Would be interesting to hear an update (six years later...) on how your migration went, and if it was worth it. – ruffin Apr 03 '15 at 18:58
5

Can you clarify what you mean by "LINQ"?

LINQ isn't an data access technology, it's just a language feature which supports querying as a native construct. It can query any object model which supports specific interfaces (e.g. IQueryable).

Many people refer to LINQ To SQL as LINQ, but that's not at all correct. Microsoft has just released LINQ To Entities with .NET 3.5 SP1. Additionally, NHibernate has a LINQ interface, so you could use LINQ and NHibernate to get at your data.

Jon Galloway
  • 50,160
  • 24
  • 120
  • 192
2

By LINQ, I'm assuming you mean LINQ to SQL because LINQ, by itself, has no database "goings on" associated with it. It's just an query language that has a boat-load of syntac sugar to make it look SQL-ish.

In the very basic of basic examples, NHibernate and LINQ to SQL seem to both be solving the same problem. Once you get pass that you soon realize that NHibernate has support for a lot of features that allow you to create truly rich domain models. There is also a LINQ to NHibernate project that allows you to use LINQ to query NHibernate in much the same way as you would use LINQ to SQL.

Ryan Rinaldi
  • 3,479
  • 2
  • 19
  • 22
1

First let´s separate two different things: Database modeling is concerned about the data while object modeling is concerned about entities and relationships.

Linq-to-SQL advantage is to quickly generate classes out of database schema so that they can be used as active record objects (see active record design pattern definition).

NHibernate advantage is to allow flexibility between your object modeling and database modeling. Database can be modeled to best reflect your data taking in consideration performance for instance. While your object modeling will best reflect the elements of the business rule using an approach such as Domain-Driven-Design. (see Kevin Pang comment)

With legacy databases with poor modeling and/or naming conventions then Linq-to-SQL will reflect this unwanted structures and names to your classes. However NHibernate can hide this mess with data mappers.

In greenfield projects where databases have good naming and low complexity, Linq-to-SQL can be good choice.

However you can use Fluent NHibernate with auto-mappings for this same purpose with mapping as convention. In this case you don´t worry about any data mappers with XML or C# and let NHibernate to generate the database schema from your entities based on a convention that you can customize.

On the other hand learning curve of Linq-to-SQL is smaller then NHibernate.

Humberto
  • 33
  • 1
  • 4
0

Or you could use the Castle ActiveRecords project. I've been using that for a short time to ramp up some new code for a legacy project. It uses NHibernate and works on the active record pattern (surprising given its name I know). I haven't tried, but I assume that once you've used it, if you feel the need to drop to NHibernate support directly, it wouldn't be too much to do so for part or all of your project.

0

As you written "for a person who have not used either of the them" LINQ to SQL is easy to use so any one can use it easily It also support procedures, which helps most of the time. Suppose you want to get data from more than one table then write a procedure and drag that procedure to designer and it will create everything for you, Suppose your procedure name is "CUSTOMER_ORDER_LINEITEM" which fetch record from all these three table then just write

MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();

you can use you records object in foreach loop as well, which is not supported by NHibernate

Ali Adravi
  • 18,401
  • 7
  • 70
  • 77