Title: Using SimpleMembership with EF model-first
Tags: entity-framework;simplemembership
Question: Can SimpleMembership be used with EF model-first?  When I try it, I get "Unable to find the requested .NET Framework Data Provider" when I call ```WebSecurity.InitializeDatabaseConnection.```

To put it another way: I can't get the call to ```WebSecurity.InitializeDatabaseConnection``` to work when the connection string employs the ```System.Data.EntityClient``` provider (as it does when using the model-first paradigm).

To repro the issue, create an MVC 4 app, and replace the code-first UserProfile entity class (which you get for free with the MVC 4 template) with a model-first User class that you have created in the Entity Designer:


Create an MVC 4 app in VS 2012 and add a new, blank Entity Data
Model.
Add a new Entity named ```User``` to the model, with fields for ```Id,```
```UserName, and FullName```.  So, at this point, the ```User``` data entity is
mapped to a ```Users``` table and is accessed via a funky connection
string that employs the ```System.Data.EntityClient``` provider.
Verify that the EF can access the ```User``` entity.  One easy way to do
that is to scaffold out a Users controller based on the User table
and its associated DbContext.
Edit the ```AccountModels.cs``` file to remove the ```UserProfile``` class and
its associated ```UsersContext``` class. Replace the references to the
(now missing) ```UserProfile``` and ```UsersContext``` classes with references
to your new User class and its associated ```DbContext``` class.
Move the call to InitializeDatabaseConnection from the
InitializeSimpleMembershipAttribute filter class to the
Application_Start method in Global.asax.cs.  While you're at it,
modify the arguments to use your new User entity's connection
string, table name, and UserId column name.
Delete the (no longer used) ```InitializeSimpleMembershipAttribute```
class and the references to it.


When you run the repro, it will get an Exception at the call to ```InitializeDatabaseConnection.```

Bob

Comment: @PeterEdike Yes, that's what I tried to do.  I tried to replace all of the code-first stuff with my model-first stuff, but I discovered that SimpleMembership doesn't work with the model-first magic in the connection string. As Mario Zderic says, the solution is to use something that looks like the code-first connection string.

Comment: Do you mean replace    public DbSet UserProfiles { get; set; } with    (public DbSet userProfiles{get;set;}). I am kind of in a fix with this

Here is the accepted answer: SimpleMembership can work with model first. Here is the solution.

1.```InitializeSimpleMembershipAttribute.cs``` from MVC 4 Internet Application templete should look like this 

```namespace WebAndAPILayer.Filters
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute
    {
        private static SimpleMembershipInitializer _initializer;
        private static object _initializerLock = new object();
        private static bool _isInitialized;

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Ensure ASP.NET Simple Membership is initialized only once per app start
            LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
        }

        private class SimpleMembershipInitializer
        {
            public SimpleMembershipInitializer()
            {
                try
                {
                    WebSecurity.InitializeDatabaseConnection("ConnStringForWebSecurity", "UserProfile", "Id", "UserName", autoCreateTables: true);
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException("Something is wrong", ex);
                }
            }
        }
    }
}
```

2.Delete CodeFirst Classes from ```AcountModel.cs```

3.Fix ```AccountCotroler.cs``` to work with your Model-first DbContext (```ExternalLoginConfirmation(RegisterExternalLoginModel model, string returnUrl)``` method)

4.Define your ```"ConnStringForWebSecurity"``` connection string which is not same as that funky conn string for model-first db access, notice that we use provider ```System.Data.SqlClient``` not ```System.Data.EntityClient```

``` <connectionStrings&gt;
         <add name="ModelFirstEntityFramework" connectionString="metadata=res://*/Context.csdl|res://*/Context.ssdl|res://*/Context.msl;provider=System.Data.SqlClient;provider
 connection string=&amp;quot;data source=.\SQLEXPRESS;Initial
 Catalog=aspnet-MVC4;Integrated
 Security=SSPI;multipleactiveresultsets=True;App=EntityFramework&amp;quot;"
 providerName="System.Data.EntityClient" /&gt;
         <add name="ConnStringForWebSecurity" connectionString="data source=.\SQLEXPRESS;Initial Catalog=aspnet-MVC4;Integrated
 Security=SSPI" providerName="System.Data.SqlClient" /&gt;
       </connectionStrings&gt;
```

Comment for this answer: Thank you Mario!  That raises a couple of questions regarding how the two DbContext connections cooperate with each other.  I'll create new forum threads for those two questions.
Comment for this answer: I'm new to the MVC world, and now I have the same problem...,what you mean in point 2, 3, please can you have a better explanation to newbie people like me, thanks in advance.
Comment for this answer: The dual connection strings was the part I was missing in DbFirst! So essentialy the SimpleMembershipProvider helpers only work with classic connection strings and not EF connection strings.

Here is another answer: That's a bug in MVC 4. There's a workaround in this blog post.

```
  As an action filter, ```InitializeSimpleMembershipAttribute``` hooks into ```OnActionExecuting``` to perform the lazy initialization work, but this can be too late in the life cycle. The Authorize attribute will need the providers to be ready earlier if it needs to perform role based access checks (during ```OnAuthorization```). In other words, if the first request to a site hits a controller action like the following:
```

```[Authorize(Roles="Sales")]
```

```
  .. then you’ll have an exception as the filter checks the user’s role but the providers aren’t initialized.
  
  My recommendation is to remove ISMA from the project, and initialize WebSecurity during the application start event.
```

Comment for this answer: Thanks Craig. When I first embarked on my quest to fuse my model-first entities with the SimpleMembership magic, I had, in fact, removed ISMA and moved the call to InitializeDatabaseConnection from the lazy initializer to the Application_Start method in Global.asax.cs.  I just didn't want to complicate the scenario in my original posting with that detail.

The "can't find the provider" exception happens whenever I try to lash up my model-first entity to SimpleMembership, whether I make the call in the lazy initializer or in Application_Start.
Comment for this answer: Yeah, solution with 30 lines of negative code! I like that. +1

Here is another answer: this problem caused by ```WebSecurity.InitializeDatabaseConnection``` can't use connection string with ```System.Data.EntityClient``` provider name.

providing dual connection string isn't sound good, so you can generate the connection string for EF model first in the constructor in the partial class.

the code is look like bellow

```public partial class MyDataContext 
{
    private static string GenerateConnectionString(string connectionString)
    {
        var cs = System.Configuration.ConfigurationManager
                     .ConnectionStrings[connectionString];

        SqlConnectionStringBuilder sb = 
             new SqlConnectionStringBuilder(cs.ConnectionString);
        EntityConnectionStringBuilder builder = 
             new EntityConnectionStringBuilder();
        builder.Provider = cs.ProviderName;
        builder.ProviderConnectionString = sb.ConnectionString;
        builder.Metadata = "res://*/MyDataContext.csdl|" +
              "res://*/MyDataContext.ssdl|res://*/MyDataContext.msl";
        return builder.ToString();
    }

    public MyDataContext(string connectionName) : 
          base(GenerateConnectionString(connectionName)) { }
}
```

with this trick you can use single connection string on your web config, but one problem you can't use default constructor on your datacontext, instead you should seed connection string name everywhere when you instantiate the datacontext. but it is not a big problem when you use dependency injection pattern.


Here is another answer: I´m not able to work with EF and WebMatrix webSecurity class so to avoid this problem and go ahead:

Change my Ef model first to code first.

Change the connection string to use providerName="System.Data.SqlClient"(removing all the metadata information) or use the EF connection

In my case the model, data and web are different proyects so for me is not an issue to remove this information from the web.config on the web.project.

Nowadays websecuroty.initializedatabase dosen't run with EF connection string.

I wish this helps


Here is another answer: 1 - You need to enable migrations, prefereably with EntityFramework 5

2 - Move your 

```WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "EmailAddress", autoCreateTables: true); 
```

to your Seed method in your YourMvcApp/Migrations/Configuration.cs class

```    protected override void Seed(UsersContext context)
    {
        WebSecurity.InitializeDatabaseConnection(
            "DefaultConnection",
            "UserProfile",
            "UserId",
            "UserName", autoCreateTables: true);

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

        if (!WebSecurity.UserExists("lelong37"))
            WebSecurity.CreateUserAndAccount(
                "lelong37",
                "password",
                new {Mobile = "(318)549-6820", IsSmsVerified = false});

        if (!Roles.GetRolesForUser("lelong37").Contains("Administrator"))
            Roles.AddUsersToRoles(new[] {"lelong37"}, new[] {"Administrator"});
    }
```

Now EF5 will be in charge of creating your UserProfile table, after doing so you will call the WebSecurity.InitializeDatabaseConnection to only register SimpleMembershipProvider with the already created UserProfile table (In your case, you can replace the "UserProfile" parameter value with your custom table name), also tellling SimpleMembershipProvider which column is the UserId and UserName. I am also showing an example of how you can add Users, Roles and associating the two in your Seed method with custom UserProfile properties/fields e.g. a user's Mobile (number).

3 - Now when you run update-database from Package Manager Console, EF5 will provision your table with all your custom properties

For additional references please refer to this article with sourcecode: 
http://blog.longle.net/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom-user-properties/

Comment for this answer: Thanks Long Le.  Unfortunately, my problem is that I'm using "model-first", not "code-first".  As far as I know (correct me if I'm wrong) the "migrations" feature only applies to code-first, not to model-first.  But the code examples for creating roles and users will be very helpful once I get the basic claptrap working! - Bob
Comment for this answer: Bob.as.SBS - well I'm glad that at least something in my answer was helpful to you, do you mind bumping upvoting this answer since it was of some assistance to you? - thanks

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 5, 'CommentCount': 2, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2012:00:09/25/12', 'FavoriteCount': 11.0, 'PostTypeId': 1, 'Tags': '<entity-framework><simplemembership>', 'Title': 'Using SimpleMembership with EF model-first', 'ViewCount': 21296, 'id': 12575311, 'user_AboutMe': '<p>President and CTO of Indigo Health, Inc (www.indigo.health).  Our product (to be launched soon) provides a range of services to mental health professionals, including patient on-boarding (including e-signatures on all legal forms and form archival and retrieval - no more filing cabinet full of paper forms!), patient evaluation and tracking, and clinical decision support).</p>\n\n<p>Prior to AI PsychLab, spent 31 happy years building real-time airplane simulations at McDonnell Douglas/Boeing.  Specialized in simulation architecture and distributed (multi-PC, multi-process) real-time architecture.  Real-time models were entirely native code (C++, FORTRAN, Ada) that communicated with the real-time scheduling and data sharing claptrap via native libraries written in C++/CLI.  Tools, user interfaces, and some "soft" real-time components were all written in .NET (using WinForms and Remoting - none of this newfangled WCF and WPF stuff ;-).</p>\n', 'user_AccountId': 1798172.0, 'user_DisplayName': 'Bob.at.Indigo.Health', 'user_Reputation': 10247.0, 'user_Views': 579.0, 'user_id': 1637105.0}}