Customizing SimpleMembership
asp.net-mvc-4, c#, entity-framework-5, simplemembership
Solution
I struggled a lot with the same issue. The key is to get the relation between the UserProfile class and your Student class correct. It have to be a one-to-one relationship in order to work correct.
Here is my solution:
Person.cs
public class Person
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
/* and more fields here */
public virtual UserProfile UserProfile { get; set; }
}
UserProfile.cs
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public virtual Person Person { get; set; }
}
MyDbContext.cs
public class MyDbContext : DbContext
{
public DbSet<Person> Person { get; set; }
public DbSet<UserProfile> UserProfile { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<UserProfile>()
.HasRequired(u => u.Person)
.WithOptional(p => p.UserProfile)
.Map(m => m.MapKey("PersonId"));
}
}
However, I also struggled with creating users with the WebSecurity.CreateUserAndAccount method. So I ended up creating my Person objects with Entity Framework and then create the user account with the membership provider method:
AccountRepository.cs
public Person CreatePerson(string name, string username) {
Person person = new Person { Name = name };
_dbContext.Person.add(person);
_dbContext.SaveChanges();
var membership = (SimpleMembershipProvider)Membership.Provider;
membership.CreateUserAndAccount(
model.UserName,
createRandomPassword(),
new Dictionary<string, object>{ {"PersonId" , person.Id}}
);
}
Problem
After reading this good BLOG about adding custom data to UserProfile table, I wanted to change it the way that UserProfile table should store default data + another class where all additional info is stored. After creating new project using Interenet application template, I have created two classes: Student.cs ``` [Table("Student")] public class Student { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public virtual int StudentId { get; set; } public virtual string Name { get; set; } public virtual string Surname { get; set; } public virtual int UserId { get; set; } } ``` UserProfile.cs ``` [Table("UserProfile")] public class UserProfile { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int UserId { get; set; } public string UserName { get; set; } public virtual int StudentId { get; set; } public virtual Student Student { get; set; } } ``` also, I've deleted the UserProfile definition from AccountModel.cs. My DB context class looks like this: MvcLoginDb.cs ``` public class MvcLoginDb : DbContext { public MvcLoginDb() : base("DefaultConnection") { } public DbSet<UserProfile> UserProfiles { get; set; } public DbSet<Student> Students { get; set; } } ``` again, I have deleted db context definition from AccountModel.cs. Inside Package-Manager-Console I've written: ``` Enable-Migrations ``` and my Configuration.cs looks like this: ``` internal sealed class Configuration : DbMigrationsConfiguration<MvcLogin.Models.MvcLoginDb> { public Configuration() { AutomaticMigrationsEnabled = true; } protected override void Seed(MvcLogin.Models.MvcLoginDb context) { WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true); if (!WebSecurity.UserExists("banana")) WebSecurity.CreateUserAndAccount( "banana", "password", new { Student = new Student { Name = "Asdf", Surname = "Ggjk" } }); } } ``` That was the idea of adding student data as creating a new class, but this approach is not working because after running Update-Database -Verbose I'm getting the error: No mapping exists from object type MvcLogin.Models.Student to a known managed provider native type. Can anyone expain why I'm getting this error, shoud I use a different approach for storing additional data in different table?