Linq to SQL vs NHibernate Part 1: What do they have in common?
Choosing a technology such as object persistence is one of the first steps in any major project, and it's a tough call to make. We spent some time at my company trying to figure out if Linq to sql was a better ORM than NHibernate. After some experiments, I came to the engineer's conclusion: It depends. As Linq gains popularity, people will be wondering the same questions, so I'm writing a few unbiased posts to sort out their differences (just as a warning in advance, my expertise is with NHibernate)
Crash Course:
Linq is the query syntax added to the C# language for 3.0. Trees, relational data, objects, xml etc can all be queried using the common Linq syntax reminiscent of SQL. It is easy and flexible, strongly typed, and compiled. Linq to SQL is a natural extension of Linq into an ORM, and it is touted as a "lightweight" data mapper, and heavily hyped by microsoft in previous beta versions. Linq to SQL is built specifically for sql server 2005 and above.
NHibernate is a mature open source project designed specifically to solve ORM problems. It is an extremely flexible and configurable ORM, and its been battle-proven for many enterprise projects. It is database agnostic, and supports a wide array of different database brands. Like many active open-source projects, it is undergoing constant evolution, which makes good documentation hard to find.
What do they have in common?
Mapping syntax
Any object/data mapping system is going to need object definitions and and a corresponding DDL. Both libraries are extremely flexible with their initial configuration, but there is a way to use both of them in a similar fashion.
Just like any good ORM, your objects are simply plain old objects that happen to be persistable as an afterthought. The object definition is any class file. The XML mapping gives the ORM library the links between objects and their tables. It defines the mappings between an objects properties and the columns in the database. It defines the relationship between objects (collections and encapsulation) and the corresponding data relations (many-to-many, many-to-one, one-to-one)
Both NHibernate and Linq accept these mapping files as arguments to their initialization.
Persistent Object Lifecycles
Scoping - Within a common scope, the loading of two instances of the same database row should yield two references to the same object. This scope in NHibernate is called a "Session", in Linq, it is called a "DataContext", and both guarantee reference equality between two instances of the same data under the same scope.
Version Management - Once you have loaded objects under a scope, you should be able to efficiently synchronize the database with the updated state of your objects. Linq's DataContext exposes a SubmitChanges() method for this very purpose, and NHibernate has a Flush() method.
Adjustable Fetching Schemes - Loading objects from the database is a bit of a catch-22, you don't want to load the entire database up in to an object graph, but you don't want a roundtrip to the database every time you need a new object. Both of the libraries support highly configurable lazy and eager fetching schemes. Both of them use lazy loading by default, and both use left-outer-join as a default behavior when eagerly fetching peripheral objects.
Concurrency Concerns - Enterprise data is volatile, and we need an ability to recognize and manage the scenarios when data is changed by external forces. By default behavior, NHibernate and Linq behave in an optimistic concurrency fashion, which basically loads rows without locking them, and throws exceptions if the objects you are saving have changed since you loaded them. Both libraries have multiple means of customizing concurrency behavior.
Custom Database Objects - There are some operations that are simply better off left to the database to perform, such as large scale "en-masse" updates and reporting. These operations are easily implemented as stored procedures or indexed views. Both libraries support the ability to interface with custom database objects. Linq has very strong integration with stored procedures and views, but it only works with sql server 2005 and above. NHibernate is database agnostic, but there code that references database objects is string-based, which makes the connection brittle in comparison.
Code Generators
Personally, I am not a fan of any code generator related to something as important as your DDL, but there seems to be a very big demand for code generation, and there are convenience tools for both ORMs.
Linq Visual Designer - Linq comes with a built-in Visual studio designer for Linq Objects. It looks just like the visual dataset designer, because it was built by the same guy who made the visual dataset designer. IMO, this designer is a great way to get you nowhere in 30 seconds. It is only useful for the most trivial of object graph complexities, it uses partial classes to separate the mapping code from your user code, and it is brittle code at best.
Linq SQLMetal - In terms of codegens, this is Linq's saving grace right here. Given a database connection, sqlmetal can generate clean code for the objects, mappings, or both, with an array of options for fine-tuning the output code.
MyGeneration - A free 3rd-party codegen that has DDL "templates" for both NHibernate and Linq (amnong many others). This is a great way to generate code if you have an existing database schema.
NHibernate SchemaExport - All of the codegens above deal with the conversion of an existing database schema into object and mapping code. SchemaExport goes in the other direction, building a database schema from the mappings. I spoke on SchemaExport in the past, I am a very big fan of this one.
Integration -
Since the two technologies are not necessarily in direct competition, the is currently a push to harness the power of the linq-style querying in to nHibernate. More about Linq for NHibernate can be found here, here and here.
This post covers some of the commonalities, and in the next few days, I'll be comparing some of the more important factors such as performance, flexibility, and usability.
UPDATE:
PerpetuumSoft is a 3rd-party company has filled the dire need for a database synchronization tool with Linq To Sql. Given your object model definitions in Lint to SQL, their Database Restyle application is a royalty-free component that gives you the essential ability to synchronize a schema from a changing object design, so you can design from a truly object-centric point of view.
Crash Course:Linq is the query syntax added to the C# language for 3.0. Trees, relational data, objects, xml etc can all be queried using the common Linq syntax reminiscent of SQL. It is easy and flexible, strongly typed, and compiled. Linq to SQL is a natural extension of Linq into an ORM, and it is touted as a "lightweight" data mapper, and heavily hyped by microsoft in previous beta versions. Linq to SQL is built specifically for sql server 2005 and above.
NHibernate is a mature open source project designed specifically to solve ORM problems. It is an extremely flexible and configurable ORM, and its been battle-proven for many enterprise projects. It is database agnostic, and supports a wide array of different database brands. Like many active open-source projects, it is undergoing constant evolution, which makes good documentation hard to find.
What do they have in common?
Mapping syntax
Any object/data mapping system is going to need object definitions and and a corresponding DDL. Both libraries are extremely flexible with their initial configuration, but there is a way to use both of them in a similar fashion.
Just like any good ORM, your objects are simply plain old objects that happen to be persistable as an afterthought. The object definition is any class file. The XML mapping gives the ORM library the links between objects and their tables. It defines the mappings between an objects properties and the columns in the database. It defines the relationship between objects (collections and encapsulation) and the corresponding data relations (many-to-many, many-to-one, one-to-one)Both NHibernate and Linq accept these mapping files as arguments to their initialization.
Persistent Object Lifecycles
Scoping - Within a common scope, the loading of two instances of the same database row should yield two references to the same object. This scope in NHibernate is called a "Session", in Linq, it is called a "DataContext", and both guarantee reference equality between two instances of the same data under the same scope.
Version Management - Once you have loaded objects under a scope, you should be able to efficiently synchronize the database with the updated state of your objects. Linq's DataContext exposes a SubmitChanges() method for this very purpose, and NHibernate has a Flush() method.
Adjustable Fetching Schemes - Loading objects from the database is a bit of a catch-22, you don't want to load the entire database up in to an object graph, but you don't want a roundtrip to the database every time you need a new object. Both of the libraries support highly configurable lazy and eager fetching schemes. Both of them use lazy loading by default, and both use left-outer-join as a default behavior when eagerly fetching peripheral objects.
Concurrency Concerns - Enterprise data is volatile, and we need an ability to recognize and manage the scenarios when data is changed by external forces. By default behavior, NHibernate and Linq behave in an optimistic concurrency fashion, which basically loads rows without locking them, and throws exceptions if the objects you are saving have changed since you loaded them. Both libraries have multiple means of customizing concurrency behavior.
Custom Database Objects - There are some operations that are simply better off left to the database to perform, such as large scale "en-masse" updates and reporting. These operations are easily implemented as stored procedures or indexed views. Both libraries support the ability to interface with custom database objects. Linq has very strong integration with stored procedures and views, but it only works with sql server 2005 and above. NHibernate is database agnostic, but there code that references database objects is string-based, which makes the connection brittle in comparison.
Code Generators
Personally, I am not a fan of any code generator related to something as important as your DDL, but there seems to be a very big demand for code generation, and there are convenience tools for both ORMs.
Linq Visual Designer - Linq comes with a built-in Visual studio designer for Linq Objects. It looks just like the visual dataset designer, because it was built by the same guy who made the visual dataset designer. IMO, this designer is a great way to get you nowhere in 30 seconds. It is only useful for the most trivial of object graph complexities, it uses partial classes to separate the mapping code from your user code, and it is brittle code at best.
Linq SQLMetal - In terms of codegens, this is Linq's saving grace right here. Given a database connection, sqlmetal can generate clean code for the objects, mappings, or both, with an array of options for fine-tuning the output code.
MyGeneration - A free 3rd-party codegen that has DDL "templates" for both NHibernate and Linq (amnong many others). This is a great way to generate code if you have an existing database schema.
NHibernate SchemaExport - All of the codegens above deal with the conversion of an existing database schema into object and mapping code. SchemaExport goes in the other direction, building a database schema from the mappings. I spoke on SchemaExport in the past, I am a very big fan of this one.
Integration -
Since the two technologies are not necessarily in direct competition, the is currently a push to harness the power of the linq-style querying in to nHibernate. More about Linq for NHibernate can be found here, here and here.
This post covers some of the commonalities, and in the next few days, I'll be comparing some of the more important factors such as performance, flexibility, and usability.
UPDATE:
PerpetuumSoft is a 3rd-party company has filled the dire need for a database synchronization tool with Linq To Sql. Given your object model definitions in Lint to SQL, their Database Restyle application is a royalty-free component that gives you the essential ability to synchronize a schema from a changing object design, so you can design from a truly object-centric point of view.
Labels: Linq, NHibernate, sql

