1

I'm working with a system in ASP.NET MVC, with Entity Framework for ORM. The application has a requirements to allow users to have different types of roles, and authorization rules will be different for each role (.e.g. user with role A will be able to see some pages, role B will see some different pages)

In most of the systems that I work with before, this user and role relation will be modeled as:

public class User
{
    //Omitted properties
    public List<Role> Roles { get; set; }
}

public class Role
{
    //Omitted properties
}

However in this system, there are some other requirements that require user to have different properties based on different roles, .e.g. role A user will have property A + B, role B user will have property C + D. Each user, regardless of which role it has, is still be identified by a common id (Active Directory user id). And there might be a situation where an user has more than one role

I'm wondering what's the best way to model this relation. I think of some ways but haven't found one that is good enough:

Approach 1: Each user has a profile that contains properties that are different from role to role:

public class User
{
    //Omitted properties
    public List<Role> Roles { get; set; }
    public List<UserProfile> Profile { get; set; }
}

public abstract class UserProfile
{
    //Common properties
}

public class RoleAUserProfile : UserProfile
{
    //Omitted properties
}

public class RoleBUserProfile : UserProfile
{
    //Omitted properties
}

public class Role
{
    //Omitted properties
}

Problems: difficult to model with EF code first fluent api. I setup with table splitting approach but always have problem with abstract UserProfile and key. Also list of user profiles in User is not clear. When I want to get data for a specific role, need to loop through the list, check one by one

Approach 2: Different user class for different type of role:

public class User
{
    //Omitted properties
    public List<Role> Roles { get; set; }
}

public class RoleAUser : User
{
    //Omitted properties
}

public class RoleBUser : User
{
    //Omitted properties
}

public class Role
{
    //Omitted properties
}

Problems: cannot handle case one user multiple roles. Also the inheritance relationship seems awkward to me

Approach 3: Put everything in one User class:

public class User
{
    //Omitted properties

    //Role A properties

    //Role B properties

    public List<Role> Roles { get; set; }
}

public class Role
{
    //Omitted properties
}

Problems: difficult to maintain when number of properties for each role is large, difficult to use (need to know what properties belong to which roles to use correctly)

Approach 4: Similar to approach 1 but instead of creating new UserProfile, put data directly into different role class itself. Seem awkward to me

Any suggestion to how to model this situation? Maybe I over-complicate things but I haven't found any satisfying solution yet.

2 Answers 2

2

If a property is dependent only on the User, then it belongs on User; if it depends only on a Role, it belongs on Role. Clearly, if it depends on both User and Role, it belongs on a class that models the intersection of User and Role, i.e. something like Profile. A user can have many profiles; many profiles can refer to the same role, so it's just a normal many-to-many intersection entity.

0

What are those role-dependent attributes? That's strange for users to have different sets of attributes, since they can change roles in a blink. What will you do with the attributes from role A when user no longer has the role? Delete them? What if tomorrow that user will change his role back to A?

So, one approach is to maintain a single overly-bloated user profile with all possible user data. Unused data is null.

The second approach I see is to create Role objects for each users separately and store role-dependent attributes in those Role objects. As for database storage, you can put them into pivot table of User-To-Role relation.

Is that suitable for you?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.