I am setting up a dev, qa, staging, production system of deployment. I
would like to be able to promote a release from one environment to the
next without having to re-publish from VS, and without manually
touching any files.
This is really strange and bad requirement. It is absolutely common to reconfigure application during deployment to different environment. Instead of hardcoding this in your application you should have different set of installation / deployment scripts which would also change your configuration file when moving from one environment to another.
Holding configuration for all environments in the configuration is IMHO very bad practice.
Even with hardcoded solution you still need to change some "configuration" to tell application which environment it currently runs on. Hardcoded solution will use information about environment to select correct connections string from configuration file and pass it to context constructor.
As example of the mentioned approach you can try this. It will still require you to change environment variable each time you redeploy application - complexity of such modification in custom deployment script is exactly the same as replacing connection string:
Configuration file:
<appSettings>
<add key="environment" value="Dev"/>
</appSettings>
<connectionStrings>
<add name="Dev" connectionString="..."/>
</connectionStrings>
Code for context factory method:
public static YourContext ContextFactory()
{
string environment = WebConfigurationManager.AppSettings["environment"].Value;
// This should be correctly recognized as a name of connection string.
return new YourContext(environment);
}
Context:
public class YourContext : DbContext
{
public YourContext(string connectionStringName) : base(connectionStringName)
{ }
}