I have a class Landlord
that inherits from UserProfile
using table-per-type inheritance.
When a new user registers on the application, they enter some criteria and select the type of account they want, either Landlord
or Tenant
.
Here's my AccountController/Register method:
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password,
new
{
Email = model.Email,
FirstName = model.FirstName,
LastName = model.LastName,
AccountType = model.AccountType.ToString()
},
false);
// Add user to role that corresponds with selected account type
if (model.AccountType == AccountType.Tenant)
{
try
{
Roles.AddUserToRole(model.UserName, "Tenant");
using (var db = new LetLordContext())
{
var tenant = db.UserProfile.Create<Tenant>();
tenant.TenantAge = null;
tenant.TenantGroupMembers = null;
tenant.UserId = WebSecurity.CurrentUserId;
tenant.UserName = model.UserName;
// more properties associated with tenant
// ...
db.UserProfile.Add(tenant);
db.SaveChanges();
}
}
catch (ArgumentException e)
{
ModelState.AddModelError("Unable to add user to role", e);
}
}
if (model.AccountType == AccountType.Landlord)
{
try
{
Roles.AddUserToRole(model.UserName, "Landlord");
using (var db = new LetLordContext())
{
var landlord = db.UserProfile.Create<Landlord>();
// same idea as adding a tenant
}
}
catch (ArgumentException e)
{
ModelState.AddModelError("Unable to add user to role", e);
}
}
return RedirectToAction("Confirm", "Home");
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
As an example, if I selected Tenant
as the desired account type when registering, WebSecurity.CreateUserAndAccount
would add a user into the UserProfile
table, correctly, with say a UserProfileId
of 1.
Then, if (model.AccountType == AccountType.Tenant)
would see that the selected account type is Tenant
, add the user to that role, with a UserProfileId
of 1 and a RoleId
of 1. Within this if-statement
, because selected role is Tenant
, I create a new Tenant
like so: var tenant = db.UserProfile.Create<Tenant>();
and it is saved to the database (with correct UserProfileID as the PK).
The problem: Two UserProfile
entities (two rows) are being added to the UserProfile
table each time I try to register ONE user. I understand that this is probably due to the fact that I am calling WebSecurity.CreateUserAndAccount
AND I'm creating a new Tenant
object.
How do I avoid this situation?
How do I add the model being used in WebSecurity.CreateUserAndAccount
into UserProfile
table and Tenant
table ONCE?