“The Provider encountered an unknown error” when creating new users in EF DbMigrationsConfiguration.Seed method

The objective was to create some default users in EF Seed method so we could login without having a link for new user registration in application.

The code that we have was as below.


WebSecurity.InitializeDatabaseConnection("DbContext", "UserAccounts", "Id", "UserLogOnId", true);

 if (!WebSecurity.UserExists("Test1"))
 {
 WebSecurity.CreateAccount("Test1", "123456", false);
 }

 context.UserAccounts.AddOrUpdate(
 u => u.UserLogOnId,
 new UserAccount
 {
 UserLogOnId = "Test1",
 UserDisplayName = "Test Staff 1",
 Status = UserAccountStatus.Enabled,
 ModifiedBy = string.Empty,
 EmailAddress = "user1@gmail.com",
 LastModifiedDate = new DateTimeOffset(DateTime.UtcNow, TimeSpan.Zero),
 LastLogOnDateTime = new DateTimeOffset(DateTime.UtcNow, TimeSpan.Zero)
 },

When we called update-database from nuget console, we got this error below. It was a bit weird because we already had  all required assemblies referenced in the project and we had the correct configuration in app.config as well. Why did we get this error?

Error Message

Running Seed method.
System.Web.Security.MembershipCreateUserException: The Provider encountered an unknown error.
at WebMatrix.WebData.SimpleMembershipProvider.CreateAccount(String userName, String password, Boolean requireConfirmationToken)
at WebMatrix.WebData.WebSecurity.CreateAccount(String userName, String password, Boolean requireConfirmationToken)
at MyProject.Migrations.Configuration.Seed(MyDbContext context) in c:\Users\root\Desktop\MyProject\codes\src\Models\Migrations\Configuration.cs:line 39
at System.Data.Entity.Migrations.DbMigrationsConfiguration`1.OnSeed(DbContext context)
at System.Data.Entity.Migrations.DbMigrator.SeedDatabase()
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.SeedDatabase()
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.b__b()
at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.b__0()
at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
The Provider encountered an unknown error

EF Seed and WebSecurity - 1

Solution

Yes. The error message might be a bit misleading. But we realized about the problem after looking at the API below. You can’t create the account without creating the user. That’s why we got this error above. Its nothing related to the provider.

Here, as you can see,  this API below allows us to create both user and account at the same time and you can pass the custom properties that you can for user table.

WebSecurity.CreateUserAndAccount

Here is the correct code that you should use if you want to create a default user from Seed method. Of course, don’t forget to add the required assemblies as references in your startup project.


WebSecurity.InitializeDatabaseConnection("DbContext", "UserAccounts", "Id", "UserLogOnId", true);

 if (!WebSecurity.UserExists("Test1"))
 {
 WebSecurity.CreateAccount("Test1", "123456",
   new {
          UserDisplayName = "Test Staff 1",
          Status = UserAccountStatus.Enabled,
          ModifiedBy = string.Empty,
          EmailAddress = "user1@gmail.com",
          LastModifiedDate = new DateTimeOffset(DateTime.UtcNow, TimeSpan.Zero),
          LastLogOnDateTime = new DateTimeOffset(DateTime.UtcNow, TimeSpan.Zero)
     }
 );
 }

Hope it helps.

Tip: EF Command Error

If you are using Entity framework in Visual Studio, you might notice that EF’s cmdlet are not working in nuget console sometimes. It’s because EF module is not loaded in nuget console for some reasons.

Error Message

The term ‘update-database’ is not recognized as the name of a cmdlet, function, script file, or operable program. Che
ck the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:16
+ update-database <<<< -script
+ CategoryInfo : ObjectNotFound: (update-database:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

image001

Solution

You can use the following command to import the EF module.


Import-Module C:\Work\branches\v1\src\packages\EntityFramework.5.0.0\tools\EntityFramework.psd1

Tip: EF CodeFirst – Deleting child records

Error Message

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

Solution

Have you ever encountered problems in deleting the child records? One team member from my team got that problem a couple of months back.. The only solution that I found is that you need to change the state of child object to “Deleted” instead of using “Remove()” function. The code below is to show you how to delete the child records. Please focus on “DeleteAllChildren()”. Please let me know if you have a better solution for this issue. Thanks!

public class TestDbContext : DbContext
{
public DbSet Parent { get; set; }
}

public class Parent
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection Children { get; set; }
}

public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public string Name { get; set; }
}

private static void DeleteAllChildren()
{
var context = new TestDbContext();

var existingRecord = context.Parent.Include(c => c.Children).First();

for (var i = existingRecord.Children.Count - 1; i >= 0;i-- )
{
var child = existingRecord.Children.ElementAt(i);
var dbEntity = context.Entry(child);
dbEntity.State = System.Data.EntityState.Deleted;
}

context.SaveChanges();

Console.WriteLine("Done");
Console.ReadLine();
}

private static void Create()
{
var parent = new Parent()
{
Name = "M",
Children = new Collection{
new Child (){ Name ="A"},
new Child (){ Name ="B"}
}
};

var context = new TestDbContext();
context.Parent.Add(parent);

context.SaveChanges();
}
var context = new TestDbContext();
var first = context.Parent.First();
context.Parent.Remove(first);
context.SaveChanges();