Summary
I’m currently researching all my options regarding ORM’s. In my previous posts I talked about NHibernate and how to setup a simple example. This time I’m going to demonstrate how Fluent NHibernate works and how you can use it to avoid setting up xml documents for mapping your tables.
Project Setup
Create an empty console application in Visual Studio. Go to your NuGet window (Tools -> NuGet Package Manager -> Manage NuGet Packages For Solution…). Search for FluentNHibernate and add the package to your project.
Next, create a subdirectory inside the project called “domain”. Now create a cs file named “product.cs” and copy this code into it:
using FluentNHibernate.Mapping; namespace FluentNHibernateBlogPost { public class Product { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual string Category { get; set; } public virtual bool Discontinued { get; set; } public virtual int Store { get; set; } } public class ProductMap : ClassMap<Product> { public ProductMap() { Id(u => u.Id); Map(u => u.Name).Nullable(); Map(u => u.Category).Nullable(); Map(u => u.Discontinued); Map(u => u.Store); } } }
Next, add a cs file called “store.cs” and copy this code into it:
using FluentNHibernate.Mapping; using System.Collections.Generic; namespace FluentNHibernateBlogPost { public class Store { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual string Address { get; set; } public virtual string City { get; set; } public virtual string Zip { get; set; } } public class StoretMap : ClassMap<Store> { public StoretMap() { Id(u => u.Id); Map(u => u.Name).Nullable(); Map(u => u.Address).Nullable(); Map(u => u.City).Nullable(); Map(u => u.Zip).Nullable(); } } }
Now we need the session factory. Create a cs file in the root directory and name it “SessionFactory.cs”, copy this code into it (modify your connection string to match your database, you can copy it right out of the xml file from the previous project, if you got that to work):
using FluentNHibernate.Cfg; using FluentNHibernate.Cfg.Db; using NHibernate; using NHibernate.Tool.hbm2ddl; namespace FluentNHibernateBlogPost { public class NHibernateHelper { private static ISessionFactory _sessionFactory; private static ISessionFactory SessionFactory { get { if (_sessionFactory == null) { _sessionFactory = Fluently.Configure() .Database(MsSqlConfiguration.MsSql2005 .ConnectionString("Server=localhost;Initial Catalog=sampledata;Integrated Security=True")) .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Program>()) .ExposeConfiguration(config => { SchemaExport schemaExport = new SchemaExport(config); }) .BuildSessionFactory(); } return _sessionFactory; } } public static ISession OpenSession() { return SessionFactory.OpenSession(); } } }
Now you can write a query and access your data. For this sample, I’m going to use the exact same query that I did in my previous blog post just to demonstrate that the output will be identical. Modify your Program.cs file to look like this:
using System; using System.Linq; using NHibernate; using NHibernate.Linq; namespace FluentNHibernateBlogPost { class Program { static void Main(string[] args) { using (ISession session = NHibernateHelper.OpenSession()) { var query = from p in session.Query<Product>() join s in session.Query<Store>() on p.Store equals s.Id where s.Id == 2 select p; foreach (var item in query) { Console.WriteLine(item.Name); } } Console.ReadKey(); } } }
That’s it. That is the entire program. No XML files. No embedded properties, no copy always properties. No special configuration files. Just code. One of the advantages that I’m looking for in this example is that this project will be easy to merge when multiple developers alter tables. When hand-merging occurs, the developer will be looking at C# code and not attempting to decipher xml.
You can download the entire project here: FluentNHibernateBlogPost.zip