nHibernate First Sample (Comparison)
Perhaps some of you have seen the NHibernate first sample application on nhforge.org. This example is trying to reproduce their
First NHibernate Application
article using nHydrate.
We want to show the ease of using nHydrate against another leading product in the industry. NHibernate has gained industry acceptance and that is why we wish to perform a comparison with this product. Many developers use NHibernate and like it. We hope that
this comparison will show some of the advantages of our product. This article is not as long as the original and it still has many large screen shots. While reading, compare the original to notice its simplicity and
lack of hand written code
First you will notice that the article (a first project article) is quite long. It contains mapping files and other such esoterica that requite you to remember steps of what to do. While all programmatic products require steps and learning, you will notice
that NHibernate has a lot of explaination to load a "Product" table from a database. We are going to reproduce this example using nHydrate.
First you do not need to define the business object. You do not need to write any code. You do not need to write a mapping XML file. With that out of the way lets create our model that follows Model Driven Architecture also known as DDD (Domain Driven Design).
First lets create a blank solution in Visual Studio. Then we right-click on the solution and add a new item. We choose the "Model Files" template section and press enter.
After we add a model to the solution we are prompted for by a wizard for more information. From here we can import an existing database into our mode or just create one from scratch. Since the NHibernate example created one we will too. Press the cancel button
to escape out of the wizard and we will do it the hard way just like NHibernate.
Notice that this editor is completely integrated into Visual Studio!
There are no XML files or other configuration files to create by hand.
After we cancel the wizard we see an editor. In the editor I have changed the company name to "Acme" and the project name to "Sales". I have created an entity (table) named "Product". In this entity I have added the four fields
from the NHibernate example. I have marked the ID field as primary key, Guid. I have marked the Name field as non-nullable, string of 50, etc. Notice in the solution explorer there is only the model file (*.wsgen) and no other files or projects.
This completes out setup. We have added all necessary data into an editor that is integrated into Visual Studio and there is no other setup required. Now let's generate some code.
In this example we are going to generate an Entity Framework data access layer (DAL) and a database installer project. The EFDAL has a set of interfaces and (optional) mocks. The database installer can create a database or upgrade an existing one. The installation
project has a lot of functionality including embedding ZIP files of SQL scripts, static data, etc. The installer is a seperate topic of discussion since it provides so much functionality to you. When we press OK button on the generator dialog we see many four
projects generated directly into our Visual Studio solution.
Notice now that we have an EFDAL project, its Interfaces project and a set of Mocks. There is also an installer project. These are all complete .NET projects inside of our .NET solution. There is nothing else to do. We can use this code as it is.
Now we want to do some CRUD operations. The NHibernate article tell you to create a sample database which is an SDF file or you could create an MDF file and import it into full SQL Server. Thanks to the database installer project, we do not need to do any of
these steps. We simply setup the Debug action of the installer project and we can use it to create the database and also update the database any time we make changes to out model. Right click on the installer project and click the "Properties" menu.
Next set the external program to the "InstallUtil.exe" application from the Microsoft Framework folder (on my machine "C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe"). Set the command line arguments to the DLL name like
"Acme.Sales.Install.dll". Now you can right click on the installer project and choose Debug|Start New Instance.
You will want to check the "Save Settings" box. When you make changes to your model and regenerate the SQL difference scripts will be generated and you can run the installer again to update your database to the latest version.
Now we have a database so let run some CRUD operations. First we need to define a connection string. Create an App.Config file and add a connection string section with the Entity Framework connection string. Entity Framework connection strings are a little
complex and I assume you know how to create them.
At this time the NHibernate article tells you to write interfaces (by hand) for the Product class (that you also wrote by hand). We do this so we can define a persistence ignorant (PI) interface and later write unit tests. Now in NHibernate we would create
a mock persistance layer that inherits from the same interface as our real repository. This is not necessary since we have a generated "Mocks" layer. We already have a mock "SalesEntities" object that inherits from the "ISalesEntities"
interface just like the real Entity framework context. Since we do not have to do this let's skip to the next step.
Next NHibernate wants to ensure that all of our properties are defined with the virtual keyword. This is a lot to remember if you have hundreds of entities and thousands of fields. Luckily all of our properties are already defined with this keyword, do let's
skip to the next step. We will now create a unit test to insert a Product entity.
Notice that so far we have written no code, no XML files, and have not fat fingered any information. This is a very big deal!!
Look at the original NHibernate article and really look at how much code you must write by hand. Keep in mind that in a real
world application you will have tens if not hundreds of tables with thousands of fields. Do not forget to write your mapping files in straight XML too! Also
, your interfaces, Entity Framework DAL, mocks, and database always stay in sync! Change the underlying model as much as you want.
Now we can actually write some code. I know developers want to write code so here we are, ready to write our first line of code. First we need add the EFCore assembly as well as the EFDAL.Interfaces, and EFDAL.Mocks to the unit test project. We do not need
the actual EFDAL project since we are mocking and not actually writing to a real database. All of that stuff above where I defined the database and setup the connection string is not even needed, since we are mocking. However it does show you how easy it is
to create (and maintain) a database with zero code.
Now we create the unit test which is almost line for line to the NHibernate unit test except that we use a syntax that
mirrors Entity Framework.
Now we have written a unit test based on Entity Framework with mocking that mirrors the NHibernate article...except that we use EF syntax. You can take the exact same code and paste it in a real project and hit a real database with the same results.
That is a unit test.