views:

215

answers:

1

Hello. I'm trying out SharpArchitecture and want to have FluentNHibernate generate my database schema for my MVC WebSite.

I'm a bit lost on where to do this. I can do it by adding the SchemaUpdate thingy in the global.asax.cs-file right after NHibernateInitializer.Instance().InitializeNHibernateOnce(InitializeNHibernateSession); in "Application_beginrequest". (If I place it before that call, SharpArch throws an exception).

This doesn't seems right and it smells bad. It feels like I'm missing something basic in the Sharp Architecture that allows for automatic schema generation to my DB (MSSQL2005). Or am I not? If not, please fill me in on best practices for schema generation with fluent nhibernate and Sharp Architecture.

Thanks in advance!

Edit: I might add that I'm looking on the Northwind sample project in SharpArch, but want to make FNHb generate the schema instead.

+1  A: 

You don't want to do it in Application_BeginRequest.

To auto-gen the DDL, what you should do is do it in your TDD classes. Create a special class that you can manually call when you need to generate your DDL for your development database.

Something like:

private static void CreateDatabaseFromFluentNHibernateMappings()
{
    var mappingAssemblies = RepositoryTestsHelper.GetMappingAssemblies();
    SchemaExport schema = new SchemaExport(NHibernateSession.Init(new SimpleSessionStorage(), mappingAssemblies, NHIBERNATE_CFG_XML));
    schema.Execute(true, true, false);
}

This will generate and execute the DDL based on your mappings to the database you specify in your NHibernate config file (in the NHIBERNATE_CFG_XML). The database, albeit empty, should already exist.

You can also create another method in your class that can update the schema of the development database as you develop in case you have added new entities, properties, etc.

private static void UpdateExistingDatabaseFromFluentNHibernateMappings()
{
    var mappingAssemblies = RepositoryTestsHelper.GetMappingAssemblies();
    SchemaUpdate schema = new SchemaUpdate(NHibernateSession.Init(new SimpleSessionStorage(), mappingAssemblies, NHIBERNATE_CFG_XML));
    schema.Execute(true, true);
}

This will update an existing database with the changes you have made in FNH without destroying the existing database. Very useful, especially when you might have test data already in the database.

And finally, You can use NDbUnit to preload a database based on test data defined in XML in your project and under SCM. Great when you have a team working on the same database and you want to preload it with data, thus everyone starts with the same blank slate.

Using NDbUnit:

private static void LoadTheTestDataintoDb()
{
    const string connectionstring = // your connection string to your db
    NDbUnit.Core.INDbUnitTest sqlDb = new NDbUnit.Core.SqlClient.SqlDbUnitTest(connectionstring);
    sqlDb.ReadXmlSchema(/* your XML schema file defining your database (XSD) */);
    sqlDb.ReadXml(/* Your XML file that has your test data in it (XML) */);
    // Delete all from existing db and then load test data allowing for identity inserts
    sqlDb.PerformDbOperation(NDbUnit.Core.DbOperationFlag.CleanInsertIdentity);
}

This requires you to use NDbUnit. Thanks to Stephen Bohlen for it!

I hope this helps; I wrote this kinda quickly, so if I confused you, let me know.

Todd Brooks
Thank you Todd! I was starting to think about doing a separate console application just to generate the schema, but doing it with the rest of my tests seems like a good idea.Thanks for all the great code examples, they'll sure help a lot!
Jaynard