Day 8 – Understanding some of Fluent NHibernate

As mentioned in Day 7, I got a Fluent NHibernate FNH example from Dan’s Development Blog, and it is very useful.

Dan has, for example’s purpose, gathered his 3 entities in a single file so one can see how they can be built, the mapping classes are saved in another file, the configuration of FNH in a third and the program in a fourth.

The example is not perfect or the best, but to understand what it takes to make a database through FNH it gives you the idea.

So – what did I do:
It’s not tested in any way yet but it runs:

Create a folder called Entities for an entity or two:

    public class Settings
    {
        public virtual int Id { get; protected set; }
        public virtual string Direction { get; set; }
        public virtual int Speed { get; set; }
        public virtual bool Active { get; set; }
        public virtual User ChangedBy { get; set; }
        public virtual DateTime CreateDate { get; protected set; }

        public Settings()
        {
            CreateDate = DateTime.Now;
        }
    }

    public class User
    {
        public virtual int Id { get; protected set; }
        public virtual string FirstName { get; set; }
        public virtual string LastName { get; set; }
        public virtual DateTime ChangeDate { get; protected set; }
        public virtual IList<Settings> Settings { get; set; }

        public User()
        {
            Settings = new List<Settings>();
            ChangeDate = DateTime.Now;
        }

        public virtual void AddSetting(Settings setting)
        {
            setting.ChangedBy = this;
            Settings.Add(setting);
        }
    }

Map the code (How FNH works with mapping and… everything, go to the official website for Fluent NHibernate):

    public class SettingsMapping : ClassMap<Settings>
    {
        public SettingsMapping()
        {
            Id(s => s.Id).Not.Nullable();
            Map(s => s.Speed).Not.Nullable();
            Map(s => s.Active).Not.Nullable();
            Map(s => s.Direction).Not.Nullable();
            Map(s => s.CreateDate).Not.Nullable();
            References(s => s.ChangedBy)
                .Cascade.None();
        }
    }

    public class UserMapping : ClassMap<User>
    {
        public UserMapping()
        {
            Id(u => u.Id)
                .Not.Nullable();
            Map(u => u.FirstName).Not.Nullable();
            Map(u => u.LastName).Not.Nullable();
            Map(u => u.ChangeDate).Not.Nullable();
            HasMany(u => u.Settings)
                .KeyColumn("ChangedBy")
                .Inverse()
                .Cascade.All();
        }
    }

Setup a configuration:

        private const string DbFile = "ECHDatabase";

        public Configuration CreateSessionFactory()
        {
            var conf = Fluently.Configure()
                .Database(
                    SQLiteConfiguration.Standard
                        .UsingFile(DbFile)
                )
                .Mappings(m =>
                          m.FluentMappings.AddFromAssemblyOf<User>());
            return conf.BuildConfiguration();
        }

The mapping is quite cleaver; You tell NHibernate to look for the assembly with User in it. Since it is placed in the folder ‘Entities’ and with the same namespace as the rest of the entities NHibernate finds the rest of the entities to map.

I have used a flat file (DbFile) to store my database in but I could have written a path to a MS database with this:

...
.Database(
    .ConnectionString(@"Server=localhost\SQLExpress;
          Database=ADatabase;
          Trusted_Connection=True;")

Afterwards the ISessionFactory just needs to be retrieved:

        public ISessionFactory SessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                    _sessionFactory = CreateSessionFactory()
                                        .BuildSessionFactory();

                return _sessionFactory;
            }
        }

And finally the Scheme can be created. I have not looked that much at this and I’m pretty sure there are better ways to do this:

        public void BuildSchema(Configuration config)
        {
            // delete the existing db on each run
            if (File.Exists(DbFile))
                File.Delete(DbFile);

            // this NHibernate tool takes a configuration (with
            // mapping info in) and exports a database schema
            // from it
            new SchemaExport(config)
                .Create(false, true);
        }

To access the database the following can be done:

public static IEnumerable<User> GetUsers()
{
	using(var session = ConfigurationBuilder.SessionFactory
					.GetCurrentSession())
	{
		using (var tx = session.BeginTransaction())
		{
			var users = session.QueryOver<User>()
			.List();
			tx.Commit();
			return users;
		}
	}
}

More on this later, since this does not flow well with Unity.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>