I am working on a project using ASP.Net MVC4 where I use SimpleMembership to deal with membership system .
In addition of UserProfile table where should I store default data, I have two tables in my own database (Student , Teacher ) .
I customized the registration adding a new field where I ask the new user to define whether he is a teacher or a student .
public class UsersContext : DbContext
{
//public UsersContext()
// : base("DefaultConnection")
//{
//}
public DbSet<Student> Students { get; set; }
public DbSet<Teacher> Teachers { get; set; }
public DbSet<UserProfile> UserProfiles { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<UserProfile>()
.HasRequired(u => u.Student)
.WithOptional(p => p.UserProfile)
.Map(m => m.MapKey("IDStudent"));
modelBuilder.Entity<UserProfile>()
.HasRequired(u => u.Teacher)
.WithOptional(p => p.UserProfile)
.Map(m => m.MapKey("IDTeacher"));
}
}
And the Table of User Profile is becoming like this
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string AccountType { get; set; }
public virtual Student student { get; set; }
public virtual Teacher teacher { get; set; }
}
I have added this a foreign key in the both classes Student , Teacher
public virtual UserProfile UserProfile { get; set; }
On Account Controller / Register Class
WebSecurity.CreateUserAndAccount(
model.UserName,
model.Password,
new { AccountType = model.AccountType },
false);
WebSecurity.Login(model.UserName, model.Password);
UsersContext db = new UsersContext();
var membership = (SimpleMembershipProvider)Membership.Provider;
membership.ValidateUser(model.UserName, model.Password);
membership.ConfirmAccount(model.UserName, model.Password);
UserProfile user = db.UserProfiles.FirstOrDefault(u => u.UserName.ToLower() == model.UserName.ToLower());
if (model.AccountType == "Teacher")
{
if (userid != null)
CreateNewTeacher(user.UserId , model.UserName);
}
if (model.AccountType == "Student")
{
if (userid != null)
CreateNewStudentt(user.UserId , model.UserName);
}
After writing those two classes
public void CreateNewStudent( int id, string username)
{
// Attempt to register the user
using (UsersContext db = new UsersContext())
{
Student student = new Student {User_Name = username};
student.id=id;
db.Students.Add(student);
db.SaveChanges();
}
}
public void CreateNewTeacher(int id,string username)
{
using (UsersContext db = new UsersContext())
{
Teacher teacher = new Teacher();
teacher.id=id;
db.Teacher.Add(teacher);
db.SaveChanges();
}
}
My Question is : At what level should I create the user in my own table (I would like to keep the same ID ) . So , I would like to know when the simple membership create the user in its tables to copy it in mine .
How Can I get the ID of the user !
Does my strategy to deal with the Accounting good ! or am I wrong in thinking that way .
UPDATE I have added [key] (It hasn't been generated )
public partial class Agent
{
public Teacher()
{
this.Tasks = new HashSet<Tasks>();
}
[Key]
public int ID_Teacher { get; set; }
public string Name_Teacher { get; set; }
public System.DateTime Bday_Teacher { get; set; }
public string User_Name { get; set; }
public virtual ICollection<Task> Tasks { get; set; }
}
public partial class Task
{
[Key, ForeignKey("Teacher"), Column(Order = 0)]
public int ID_Teacher { get; set; }
[Key, ForeignKey("Student"), Column(Order = 1)]
public int ID_Student { get; set; }
[Key, ForeignKey("DateT"), Column(Order = 2)]
public int ID_DateT { get; set; }
[Key]
public Nullable<int> ID_Comment { get; set; }
public virtual Teacher Teacher { get; set; }
public virtual Student Student { get; set; }
public virtual DateT DateT { get; set; }
}
I appreciate your time and efforts !
Regards ,
You need to created a one-to-one
relationship between UserProfile and Student
, also between UserProfile and Teacher
. I usually use Property Mapping
rather than fluent api
Try this for Entities, i went ahead and created a relationship between Teacher and Student
for you:
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string AccountType { get; set; }
}
public class Teacher
{
[Key]
[ForeignKey("UserProfile")]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.none)]
public int UserId { get; set; }
public string Name { get; set; }
public virtual ICollection<Student> Student{ get; set; }
public virtual UserProfile UserProfile { get; set; }
}
public class Student
{
[Key]
[ForeignKey("UserProfile")]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.none)]
public int UserId { get; set; }
[ForeignKey("Teacher")]
public int? TeacherId{ get; set; }
public string Name { get; set; }
public virtual UserProfile UserProfile{ get; set; }
public virtual Teacher teacher { get; set; }
}
In your Account Controller try this:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { AccountType = model.AccountType }, false);
WebSecurity.Login(model.UserName, model.Password);
var userProfile = db.UserProfiles.Local.SingleOrDefault(u => u.UserName == User.Identity.Name)
?? db.UserProfiles.SingleOrDefault(u => u.UserName == User.Identity.Name);
if (userProfile.AccountType.ToLower() == "teacher")
{
return RedirectToAction("Create", "Teacher"); //Created a Teacher Controller separate
}
return RedirectToAction("Create", "Student"); //same with Student
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Your Student
or Teacher
Create Actions should look like this inside Student or teacher Controllers:
//
// GET: /Student/
[HttpGet]
public ActionResult Create()
{
return View();
}
//
// POST: /Student/
[HttpPost]
public ActionResult Create(StudentViewModel model)
{
if (ModelState.IsValid)
{
using (UsersContext db = new UsersContext())
{
var userProfile = db.UserProfiles.Local.SingleOrDefault(u => u.UserName == User.Identity.Name)
?? db.UserProfiles.SingleOrDefault(u => u.UserName == User.Identity.Name);
if (userProfile != null)
{
var student= new Student
{
UserProfile = userProfile,
Name= model.Name
};
db.Students.Add(student);
db.SaveChanges();
}
}
}
return View(model);
}