views:

642

answers:

5

So, newbie NHibernate user; trying to wrap my brain around it.

I'm contemplating how to handle deployment, and later injection of add-ons to a web app (which may require their own persistence classes).

I was thinking that using SchemaExport for the deployment would work pretty well, but I was wondering if there's a way too get NHibernate to tell me in a common, code-based way that a schema export has been done already, or not. Basically, I want to do smething like in this pseudocode:

  if(!_cfg.HasSchemaForType(typeof(MyType))
       ExportSchema(typeof(MyType));
  else
       UpdateSchema(typefo(MyType));

where the two functions would internally use SchemaExport or SchemaUpdate, respectively.

Thanks in advance.

Paul

EDIT: Guys, I appreciate the answer so far, but they're missing the point a bit. What I'm trying to set up is a way for the application to allow for the addition and removal of add-ons which may require changes to the db. I'm not talking about versioning my own code or the like (at least, not as its primary function). So the question is less about when I deploy the app, and more about when I add or remove a plug-in. Has theis plugin (hence the pseudo-code type check) been deployed before? If so, run the update. If not, run the export. Make sense?

+3  A: 

No, NHibernate doesn't do what you're asking. I imagine it would be possible to write some code that exported the schema and then compared it to the database schema. But it would probably be easier to export into a temporary database and use a 3rd party tool, such as redgate SQL Compare, to compare the schemas.

Even if it did what you're asking, I don't see how that would help with deployment because its purpose is to create a database from scratch.

Edited to add: Assuming each plugin has its own set of tables, you could determine if the schema has been deployed using one of several methods:

  • Attempt to load one of the plugin objects and catch the exception.
  • Examine the database schema (using SMO for SQL Server) to check if the table(s) exist.
  • Create a record in a table when a plugin is deployed.
Jamie Ide
Not trying to solve the problem of deploying the app. I added some additional notes to clarify. Thanks for your response!
Paul
I don't think he means at deploy time...this would have to be at run time or initialization time...the plug ins would have to be responsible for their own dependencies.
Webjedi
Thanks; I marked yours as 'answered' since it was the most complete. I think having a separate concern that tracks which plugins have been deployed is probably the best route to go, as you suggest in your third bullet.
Paul
A: 

If you have VS Team Suite or the Database Developer edition, it can sync and track changes and then make a deployment script that will create all the right objects for you. Also RedGate has a Schema Compare product that does the same thing if I'm not mistaken.

Webjedi
I have neither version of VS, but I'm not trying to manage this at the developer level; the intent is to build a fieldable app that admins can add/remove plugins.
Paul
+1  A: 

The purpose of schema export is to generate the complete schema from scratch. Really useful if you haven't deployed your application yet.

After the first deployment I would highly recommend using a migrations tool which will help you with further extensions/modifications of the schema. If you think a bit more ahead you will notice that you even require data manipulation (e.g. removing wrong data which has been generated due to a bug) as your application evolves. That's all a migration tool can help you with.

Take a look into:

Here is a list of more migration tools for .net answered in a SO question:

The original idea of migrations originated from Ruby on Rails and has been "cloned" into other frameworks over the past. That's why it's definitely good to read about the original idea at http://guides.rubyonrails.org/migrations.html too.

Michal
Right, I know the difference between SchemaExport and SchemaUpdate; that's why I wanted to be able to detect if the initial script has already been run.
Paul
+3  A: 

I think that what you are looking for is SchemaUpdate.Execute instead of using SchemaExport. SchemaUpdate will create the schema if it doesn't already exist, or update it if required and desired.

That works for me using both MSSQL and SQLite.

new SchemaUpdate(config).Execute(false, true);
Cocowalla
+1  A: 

Yes there is, in 3.0 at least

        public static bool ValidateSchema()
        {
            NHibernate.Tool.hbm2ddl.SchemaValidator myvalidator = new NHibernate.Tool.hbm2ddl.SchemaValidator(m_cfg);
            try
            {
                myvalidator.Validate();
                myvalidator = null;
                return true;
            }
            catch (Exception ex)
            {
                MsgBox(ex.Message, "Schema validation error");
            }
            finally
            {
                myvalidator = null;
            }

            return false;
        }

For the update part, do.

public static void UpdateSchema()
        {
            NHibernate.Tool.hbm2ddl.SchemaUpdate schema = new NHibernate.Tool.hbm2ddl.SchemaUpdate(m_cfg);
            schema.Execute(false, true);
            schema = null;
        } // UpdateSchema
Quandary