I have added SimpleMembership to my MVC4 application which uses EF code first.
I wanted to add a couple of users to my database as seed data. When I ran Update-Database
the first time everything went fine: my users and passwords were set correctly.
However when I try running it on my alpha server (from visual studio) it does not add my users.
To do this I issue the command
update-database -ConnectionString "<my alpha connection string>"
The schema will be updated, but the seed method runs without adding any data.
After some digging I modified my seed method from:
if (!WebSecurity.Initialized)
WebSecurity.InitializeDatabaseConnection("TestData", "UserProfile", "UserId", "UserName", true);
Where TestData
is the name of my connection string in the web.config file
to:
if (!WebSecurity.Initialized)
WebSecurity.InitializeDatabaseConnection("<actualConnectionString>","System.Data.SqlClient", "UserProfile", "UserId", "UserName", true);
That added the data to my alpha database.
So it would appear that when I issue an Update-Database
command, WebSecurity is ignoring that connection string and just trying to do it locally.
Is there a setting or option that I'm missing?
Edit This seeding is done in the Configuration.cs Seed method.
Disclaimer. There could be a few things tripping you up, so rolling the dice ...
Update-Database sets the connection string to use in the migrations (the Up
and Down
methods), but it doesn't impact any connection string you have "compiled into" either your data context or your calls to initialise SimpleMembership.
Therefore you can use the config file to specify both the connection strings, and an appSettings
entry with the name of the connection string to use at any one time (hard to explain in words, skip to the solution below to see it in action).
You then configure the ctor for the data context, and the call to initialise SimpleMembership (for which I recommend a single helper class) to read the connection string name from WebConfigurationManager.AppSettings["connStringName"]
.
Once you have done this, before calling Update-Database
change the appSettings
entry for the connection string name you require. You can then rely on the Update-Database
switches -StartupProjectName
(to pick up the config file) and -ProjectName
(to pick up the migrations and seeding) to do the rest for you.
(This solution also ties in nicely with xml transforms that use the build configuration name to change the config file for deployment to remote servers, where you can alter the appsettings entry, or the connection string values. You don't have to use this, as Publish Profiles for publishing from the solution explorer view can also change the connection string value for you.)
Hopefully the following describes your setup:
internal sealed class Configuration : DbMigrationsConfiguration<SomeDataContext>
SomeDataContext
is a public class SomeDataContext: DbContext
Your SomeDataContext
has
Configuration.Seed
uses the connection string of your DbContext, not the connection string you specify in Update-Database. While the latter is used for the commands in the migrations, SomeDataContext
has it's connection string name "compiled into it", so Update-Database can't change that when it runs.
Also, it is possible that:
WebSecurity
and Membership
class methods (as you state you are using SimpleMembership) Configuration.Seed
method using WebSecurity.InitializeDatabaseConnection
(hopefully, while you have multiple places to initialise this, you kept it DRY using a single class to initialise so your solution to this issue gets easier)Your WebSecurity.InitializeDatabaseConnection
call specifies a connection string name, which again is compiled into the call, so Update-Database can't change it.
One possible solution is to make your connection string name configurable through your web.config file. You can then change the connection string before calling update-database. This has the advantage that is ties in with config transforms for deployment, so you can change the connection string and/or name of the connection string when you deploy to different servers.
In your config file:
<connectionStrings>
<add name="DefaultConnection" connectionString="..." providerName="System.Data.SqlClient" />
<add name="AlphaServer" connectionString="..." providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="connStringName" value="DefaultConnection" />
</appSettings>
Example of a config transform for this:
<connectionStrings>
<add name="DefaultConnection" xdt:Locator="Match(name)" xdt:Transform="Remove"/>
</connectionStrings>
<appSettings>
<add key="connStringName" value="AlphaServer" xdt:Locator="Match(key)" xdt:Transform="Replace"/>
</appSettings>
in your data context constructor:
public DefaultDataContext()
: base(WebConfigurationManager.AppSettings["connStringName"]) { }
in your (single) call to WebSecurity.InitializeDatabaseConnection
WebSecurity.InitializeDatabaseConnection(
WebConfigurationManager.AppSettings["connStringName"]), ...
You could also use compilation symbols (e.g. define ALPHA in the build configuration) to change the connection string names at compile time, but it is less preferable than the web.config appSettings entry for a number of reasons; primarily the config entry lets you keep all the coupled information in one place so is a better solution.