2014-09-19 40 views
-1

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是否是理想的路线,还是有其他可能更好的替代方案?

回答

0

为什么你需要Teacher类?有没有不是用户的Teacher

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

如果稍后您决定管理员也可以分配给您可以使用它的东西。在我看来,这一领域更多的是不值得新课程,而且它将使数据库复杂化。

+0

我使用了'Teacher',因为它最初是合乎逻辑的,因此可以作为对象模型的一部分。它使关系易于设置。事实证明,教师模型并没有太多关系,而且比我最初想象的要少得多。 – 2014-09-19 23:53:47