开发者

EF Code first database/table initialization - WHEN does it happen?

开发者 https://www.devze.com 2023-04-13 06:32 出处:网络
My application is using EF code-first design and all generally works very well. Via a private configuration file, I can specify how I would like EF to handle changes to the db schema, and so create/r

My application is using EF code-first design and all generally works very well.

Via a private configuration file, I can specify how I would like EF to handle changes to the db schema, and so create/recreate the relevant tables as desired - the options are "never" "create", "always", "onSchemaChanged" and (for the future) "onSchemaModified".

This works well - but I am getting lost in a couple of places .....

During development, I would like to use the hook开发者_开发百科 as described in "Database in use error with Entity Framework 4 Code First" - but this seems to execute on EVERY run of my program"

 public void InitializeDatabase(Context context)
    {
        context.Database.SqlCommand("ALTER DATABASE Tocrates SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
        _initializer.InitializeDatabase(context); // Maybe this does nothing if not needed
        context.Database.SqlCommand("ALTER DATABASE Tocrates SET MULTI_USER")
    }

So .. to real my question: Is there an override that I can use to detect whether EF will ACTUALLY be trying to modify the database, so I can set this SINGLE_USER stuff when needed? And if so, can I detect the reason EF it is doing so (see my list of options above) so I can log the reason for change?...

All help and suggestions are very much appreciated.


Unless you have set the database intializer to null initializers run always once (per application lifetime) when you are using a context for the first time. What then actually happens depends on the initializer (your inner _intializer):

  • For DropCreateDatabaseAlways and CreateDatabaseIfNotExists it's clear by their name what they do.

  • For DropCreateDatabaseIfModelChanges there is only the question if the model changed or not. EF detects this by comparing a model hash with a hash stored in the database. You can check this yourself by calling...

    bool compatible = context.Database.CompatibleWithModel(true);
    

    ...within your custom InitializeDatabase and then decide based on the result if you want to send your SqlCommands or not. (Don't call this with a self-created context because it will cause the database to be intialized first before the model compatibilty is checked.) The parameter bool throwIfNoMetadata (which is true in my example) causes EF to throw an exception if the model hash in the database does not exist. Otherwise the method will return true in that case.

  • For a custom inner initializer: Whatever your code will do.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号