Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebPublish Code-First Migrations with external connectionStrings.config file

I currently have a project that utilizes Entity Framework Code-First migrations and Web Publish, where the connectionStrings are stored in the web.config file.

It has come time to move the connectionStrings outside of the web.config, and as such we put them into a connectionString.config file, and have slowcheetah transforming them on webpublish.

connectionStrings.config

<connectionStrings>
    <!-- Testing Databases -->
    <add
        connectionString="server=testserver;database=testdatabasename;user id=someid;password=*******"
        name="dbname"
        providerName="System.Data.SqlClient"
    /> 
</connectionStrings>

web.config relevant section

  <connectionStrings configSource="config\connectionStrings.config">
  </connectionStrings>

Now when I load up the dialog box for Web Publish (Build -> Publish Project), In the settings tab I receive the error

No Databases found in the project

This indicates to me that the dialog box isn't intelligent enough to see the configSource and load the data from there. I can confirm that the connectionStrings are loaded properly in my developer environment, and I can also confirm that slowcheetah is properly transforming the config into it's production environment.

Is there a way to have Visual Studio Publish see my configuration config, and allow code-first migrations?

like image 424
Nathan Lafferty Avatar asked Jan 07 '15 15:01

Nathan Lafferty


1 Answers

I had the same issue also using Entity Framework 6 code first in a separate project from the published project under .net 4.5 using Visual Studio 2013 Update 4 and using a similar share method via the connectionStrings' configSource attribute.

I list out those details because it causes a bit of a perfect storm. Trying to get out of it I encountered a few different bugs and had to hack it a few different ways, per the EF blog they know it's a mess and are re-factoring their approach. This is the best I could come up with (here be dragons):

The publish wizard doesn't seem to understand configSource so I took that off of conectionStrings in web.config leaving an empty element (you could also remove it entirely but I felt an existing but empty element preferably with a comment was more appropriate). To make it work locally I added a connection factory to make things work in debug mode (locally) and make the publish wizard find the db migration. I used a factory because a connectionString always supersedes a factory and I need to abuse that to make the project work prior to any transforms. Also make sure the string you pass to the dbcontext constructor aka "connectionStringOrDatabaseName" is both the connection string AND the database name (makes the factory generated db match the connection string db).

Now it finds the database and it works locally but it isn't really using your sharedConfig (thus will not always work on publish). To address that I then used a web.config transform to xsd:Replace/Insert the empty/missing connectionStrings element with one using configSource. If you try to publish now you'll run into the problem where an invalid connectionStrings element is produced.

Despite being so close I couldn't find/figure out a solution to that problem directly so I had to employ yet another work around: I created a custom transformation aka xsd:Import that when given a configSource attribute replaces the parent element with the one in the other file, I'll leave the implementation as an exercise to the reader.

like image 163
Rick Avatar answered Oct 19 '22 09:10

Rick