Using Hangfire, connection string given in Startup.cs throws Cannot attach file as database error

jerryh91 picture jerryh91 · Jan 14, 2015 · Viewed 13.1k times · Source

I'm utilizing Hangfire in my ASP .Net MVC Web App, it had installed successfully. I'd like to use the same LocalDb to store queued jobs for Hangfire to dequeue and process as I've used to stored data. However I'm running into the below error when I provided its connectionString or name defined in Web.config in Startp.cs. I've had no trouble adding, deleting updating data in the same localDb before hangfire.

Cannot attach the file 'c:\users\jerry_dev\documents\visual studio 2013\Projects\Hangfire.Highlighter\Hangfire.Highlighter\App_Data\aspnet-Hangfire.Highlighter-20150113085546.mdf' as database 'aspnet-Hangfire.Highlighter-20150113085546'.

Startup.cs:

public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
            app.UseHangfire(config =>
            {
                string hangfireConnectionString = @"Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-Hangfire.Highlighter-20150113085546.mdf;Initial Catalog=aspnet-Hangfire.Highlighter-20150113085546;Integrated Security=True";
                config.UseSqlServerStorage(hangfireConnectionString);
                config.UseServer();
            });
        }

My project Solution is named "Hangfire.Highlighter"

Web.config:

<connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-Hangfire.Highlighter-20150113085546.mdf;Initial Catalog=aspnet-Hangfire.Highlighter-20150113085546;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>

Answer

Jack picture Jack · Aug 30, 2015

I know this is old - but its been 9 months and I pulled my hair out over this as well - and decided to do a write-up on it here.

My solution was to just create a quick and dirty DbContext, point it to the proper connection string, and call Database.CreateIfNotExists in the constructor:

public class HangfireContext : DbContext
{
    public HangfireContext() : base("name=HangfireContext")
    {
        Database.SetInitializer<HangfireContext>(null);
        Database.CreateIfNotExists();
    }
}

In the HangfireBootstrapper.Start() method I do something like this:

public void Start()
{
    lock (_lockObject)
    {
        if (_started) return;
        _started = true;

        HostingEnvironment.RegisterObject(this);

        //This will create the DB if it doesn't exist
        var db = new HangfireContext();

        GlobalConfiguration.Configuration.UseSqlServerStorage("HangfireContext");

       // See the next section on why we set the ServerName
        var options = new BackgroundJobServerOptions()
        {
            ServerName = ConfigurationManager.AppSettings["HangfireServerName"]
        };

        _backgroundJobServer = new BackgroundJobServer(options);

        var jobStarter = DependencyResolver.Current.GetService<JobBootstrapper>();

        //See the Recurring Jobs + SimpleInjector section
        jobStarter.Bootstrap();

    }
}

Not sure why Hangfire has such a hard time with LocalDb - maybe it can only handle full-blown SQL instances? Either way this works for me, new team members, and new dev/staging/prod instances that get stood up.