3

I have an ASP.NET-MVC application with Migration enabled and SimpleMemberShipProvider configured to use my database with some extra tables/fields.

My question is, where to put my database initialization? Because i'm still developing it, i'm okay with dropping the database/tables and data and recreate it.

I have put it in the configuration.cs file, but i'm not sure if that's the place for the database initializer.

namespace CFContext.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;
    using WebMatrix.WebData;
    using System.Web.Security;
    using System.Collections.Generic;

internal sealed class Configuration : DbMigrationsConfiguration<DataContext>
{
    public Configuration()
    {
        Database.SetInitializer(new DropCreateDatabaseAlways<DataContext>());
        //Database.SetInitializer(new DropCreateDatabaseIfModelChanges<DataContext>());
        AutomaticMigrationsEnabled = true;
        AutomaticMigrationDataLossAllowed = true;
    }

    protected override void Seed(DataContext context)
    {
        //  This method will be called after migrating to the latest version.

        //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
        //  to avoid creating duplicate seed data. E.g.
        //
        //    context.People.AddOrUpdate(
        //      p => p.FullName,
        //      new Person { FullName = "Andrew Peters" },
        //      new Person { FullName = "Brice Lambson" },
        //      new Person { FullName = "Rowan Miller" }
        //    );
        //

        SeedMembership(context);
    }

    private void SeedMembership(DataContext context)
    {
        WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);

        var roles = (SimpleRoleProvider)Roles.Provider;
        var membership = (SimpleMembershipProvider)System.Web.Security.Membership.Provider;

        if (!roles.RoleExists("Administrator"))
            roles.CreateRole("Administrator");

        if (membership.GetUser("Username0", false) == null)
        {

        }
      }
    }
}

3 Answers 3

6
public class ContextInitializer : CreateDatabaseIfNotExists<Context>
{     
    private static void InitializeWebSecurity()
    {
        if (WebSecurity.Initialized)
            return;

        WebSecurity.InitializeDatabaseConnection(
            connectionStringName: "DefaultConnection",
            userTableName: "User",
            userIdColumn: "Id",
            userNameColumn: "Email",
            autoCreateTables: true);

        Roles.CreateRole("Admin");
        Roles.CreateRole("Customer");
    }       

    protected override void Seed(Context context)
    {
        InitializeWebSecurity();

        // more seeding
        context.SaveChanges();
    }
}

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.RegisterAuth();
        DatabaseConfig.RegisterDatabase();
        AutoMapperConfig.RegisterConfig();

        // Set the initializer here
        Database.SetInitializer(new ContextInitializer());

        // Now initialize it
        using (var context = new Context())
        {
            context.Database.Initialize(false);
        }

        // Double check seeding has initalized, if not
        // We initialize it here to make sure.
        if (!WebSecurity.Initialized)
        {
            WebSecurity.InitializeDatabaseConnection(
                connectionStringName: "DefaultConnection", 
                userTableName: "User", 
                userIdColumn: "Id", 
                userNameColumn: "Email", 
                autoCreateTables: false);
        }
    }
}

You should be able to create migrations the same way with this setup.

Sign up to request clarification or add additional context in comments.

5 Comments

Hi, the confusing part here is that, if you enable migrations, the configuration.cs file already has a protected override void Seed(Context context) method. Is it okay to have it on multiple places?
You should only set one initialization strategy, so CreateDatabaseIfNotExists<Context> should not be in yours. Just make sure you set the initialization strategy to use your Migrations setup. Having two different Types should not affect it.
I meant just the Seed() method which is also in the configuration.cs when migrations is enabled. I would have the Seed() method twice.
But the seed method would only be called by the Configuration.cs because that's the initialization strategy you've chosen. If you chose CreateDatabaseIfNotExists, that seed function would be called instead.
So it's okay to have the Seed() method twice? I have updated my question with the contents of configuration.cs
5

put your database initialization code into "Application_Start" method on Global.asax

4 Comments

Hi, what happens if i exec 'Update-Database' command in the NuGet console? Will it look in the Global.asax too?
It should know once you compile the assembly, what needs to happen.
I have migrations enabled in a class library. I separated the database operations from the web project.
That's how i do mine too. Then I reference my "Database" project on my MVC Project.
0

I put it inside the Application_Start in Global.asax.cs

protected void Application_Start()
        {
            WebSecurity.InitializeDatabaseConnection("Name of Connection String", "User Table in DataBase", "UserId Column", "UserName Column", true);
        }

The true, means that I want to autoCreate the tables.

In Web.config file, you need to setup the provider:

<system.web>
    <compilation debug="true" targetFramework="4.6.1" />
    <httpRuntime targetFramework="4.6.1" />

    <membership defaultProvider="nameProvider">
      <providers>
        <add name="nameProvider" type="WebMatrix.WebData.SimpleMembershipProvider,WebMatrix.WebData" />
      </providers>
    </membership>
  </system.web>

It works for me.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.