I am creating some data in the seed method. I am creating a few users with a few permissions (roles)
WebSecurity.InitializeDatabaseConnection("MibContext", "UserProfile", "UserId", "UserName", autoCreateTables: true);
Roles.CreateRole(Constants.Roles.Administrator);
Roles.CreateRole(Constants.Roles.ContentManager);
Roles.CreateRole(Constants.Roles.KeyAccountManager);
I then have variable for the username (to avoid any typo possibility)
var adminusername = "[email protected]";
var userusername = "[email protected]";
I create the Userprofile record via EF and the UnitOfWork Pattern
var admin = new UserProfile
{
FirstName = "Admin",
LastName = "Account",
UserName = adminusername
};
unitOfWork.UserRepository.Insert(admin);
unitOfWork.Save();
Then create the user Membership account, and assign roles:
WebSecurity.CreateAccount(adminusername, "123456");
WebSecurity.CreateAccount(userusername, "123456");
Roles.AddUserToRole(userusername, Constants.Roles.Administrator);
Roles.AddUserToRole(userusername, Constants.Roles.KeyAccountManager);
The last roles command causes the error, Foreign Key Violation between UsersInRoles and UserProfile. Which is very strange since it can map a role to the first user (which was the admin user first time around, but wanted to see if it could create a permission for that user, which it does)
I then removed the foreign key constraint to see what was going on, and it put a 3 in there. Testing by repeating but adding a 4th role, it seems that the (username, role) parameters are the wrong way around!?!? The new role has Id=4, and on repeating the test, that is what it put in the UserId column.
RoleId UserId
2 1
2 4
NULL NULL
Roles are configured :
<roleManager enabled="true" defaultProvider="SimpleRoleProvider">
<providers>
<clear/>
<add name="SimpleRoleProvider"
type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData" />
</providers>
</roleManager>
Am I missing something?
The order of fields in the webpages_UsersInRole table is obviously very important.
I looked at the mapping to see what was there, and the relationship (many -> many) was defined on the ROLES table side. I swapped the mapping to the Users side and it is now working correctly. Here is the mapping I used on the UserProfile object.
// Relationships
this.HasMany(t => t.webpages_Roles)
.WithMany(t => t.UserProfiles)
.Map(m =>
{
m.ToTable("webpages_UsersInRoles");
m.MapRightKey("RoleId");
m.MapLeftKey("UserId");
});
Really, the Role Provider should not assume on the order of columns and should specify their names. At least I can still use the default functionality by amending the mapping this way. This is pretty poor SQL:
INSERT INTO webpages_UsersInRoles VALUES (4,1);