查询自定义用户类型或角色?

时间:2014-09-19 20:51:43

标签: c# asp.net-mvc entity-framework asp.net-identity

EF 6,Identity 2,ASP.NET MVC 5,代码优先

我的应用程序使用Identity来管理用户;我有标准的ApplicationUser,其中包含一些附加属性:

public class ApplicationUser : IdentityUser
{
    // public async Task<ClaimsIdentity> GenerateUserIdentityAsync ...

    public int SchoolId { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string FullName
    {
        get { return String.Format("{0} {1}", FirstName, LastName); }
    }

    public virtual School School { get; set; }
}

我还使用了两个角色:adminteacher。大多数用户将拥有teacher角色,有些用户将拥有admin。甚至可能存在这样的情况:两个角色或两个角色都不适用于某个给定用户。

我还有一个Teacher模型,如下所示:

public class Teacher
{
    public int Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string FullName
    {
        get { return String.Format("{0} {1}", FirstName, LastName); }
    }

    public int SchoolId { get; set; }

    public virtual School School { get; set; }

    public virtual ICollection<TeacherAssignment> Assignments { get; set; }
}

此模型可用于将教师与各自的学校以及他们教授的课程部分联系起来。访问数据库中的教师非常简单:

public DbSet<Teacher> Teachers { get; set; } // teacher access
...
contextInstance.Teachers // get the current teachers

这一切都很好。我可以在各自的视图中管理用户及其角色,并管理教师。我的问题是代码重复,并增加了在两个地方维护教师的开销。此外,教师可能会停止教学,但仍然是用户,也许是管理员。相反,现有用户可能还需要成为一名教师。

我解决问题的想法:

1)修改Teacher模型以扩展ApplicationUser,从Teacher删除重复的属性。没有重复,直接访问。 teacher角色有点多余。此外,用户可能不再是教师,因此必须删除教师记录;相反,必须创建教师记录以伴随现有用户。所有教师都是用户,但并非所有用户都是教师。

2)保留Teacher模型,但将其连接到ApplicationUser实例:

public class Teacher {
    public int Id { get; set; }

    public int ApplicationUserId { get; set; }

    public virtual ApplicationUser ApplicationUser { get; set; }
}

分别管理教师的一些开销,以及具有相应角色的一些冗余,但可以轻松地从用户获得匹配的教师,反之亦然。同样直接的教师检索,没有回到非教师的危险。并非所有用户都会有匹配的教师记录。

3)删除Teacher模型和相关数据访问权限,并检索具有teacher角色的用户。这使得适当用户的检索稍微复杂化;之前显示的教师检索查询可以替换为对辅助函数的调用:

// within a class that receives a reference to the context
public IEnumerable<ApplicationUser> Teachers
{
    get
    {
        var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(_context));

        var role = roleManager.FindByName("teacher");
        var roleId = role.Id;

        var users = Users.Where(u => u.Roles.Any(r => r.RoleId == roleId));
        return users;
    }
}

没有重复或添加管理。用户不是活跃的老师?从teacher角色中删除用户,或将用户添加到该角色以获得另一位教师。对代码的影响应该是最小的,从直接访问变为使用辅助函数。

我的感觉是选项#3是更好的选项,因为它消除了重复,不需要单独的视图来管理另一个用户类型,并且应该直接实现。 #3看起来是理想的路线,还是有其他可能更好的替代方案?

1 个答案:

答案 0 :(得分:0)

为什么需要Teacher课程?是否有任何Teacher谁不是用户?

即使存在,通过将此属性public virtual ICollection<TeacherAssignment> Assignments { get; set; }添加到ApplicationUser类,您也不会丢失任何内存。它将被翻译成新表(TeacherId,AssignmentId)。

如果您稍后决定可以将管理员分配给某些内容,则可以使用它。在我看来,这个领域更不值得新课,而且它会使它在数据库中复杂化。