2014-09-02 73 views
2

我正在创建MVC5应用程序,并且我已经使用ASP.NET身份来创建用户。所以,我已经有了AspNetUsers表,并且每当用户注册时,我都会有一个入口。我也有一个管理员角色,我手动指定哪个注册用户是管理员。另一方面,我也需要注册企业,就像普通用户一样,他们可以登录,注册并做一些事情。重点是他们将拥有一些与普通用户相似或不同的领域。例如,他们也会拥有电子邮件地址,密码(我希望像普通用户那样对其进行散列),电子邮件确认,唯一身份证等。但他们有不同的字段以获取更多信息,例如他们的地址,邮政编码,国家,类别等普通用户没有的。我如何在MVC中实现这一点?如何在MVC5中创建两种类型的用户?

我应该像ApplicationUser类一样做什么?

public class ApplicationUser : IdentityUser 

我的意思是,我应该从IdendityUser继承我的业务模型吗?如果是,我的模型将如何知道IdentityUser的哪些字段使用哪些字段?

这是我目前的商业模式:

public class Business 
{ 
    public int BusinessID { get; set; } 

    public string BusinessName { get; set; } 

    [ForeignKey("Category")] 
    public int CategoryID { get; set; } 

    public virtual Category Category { get; set; } 

    [ForeignKey("Subcategory")] 
    public int SubcategoryID { get; set; } 

    public virtual Subcategory Subcategory { get; set; } 

    public string BusinessAddress { get; set; } 

    public string BusinessZip { get; set; } 

    public string BusinessPhone { get; set; } 

    public string BusinessDescription { get; set; } 

    public string Facebook { get; set; } 

    public string Twitter { get; set; } 

    public byte[] ImageData { get; set; } 

    public string ImageMimeType { get; set; } 

    [Range(0.0, 5.0)] 
    public double BusinessRating { get; set; } 

    public virtual ICollection<Review> Reviews { get; set; } 
} 

那么,除了这些领域,我希望我的表,包括类似于AspNetUsers的东西,比如电子邮件,EmailConfirmed,PasswordHash,SecurityStamp等

编辑:

请注意,我的商业模式中的一些领域是必需的。同样在下面你可以找到我的ApplicationUser类。

public class ApplicationUser : IdentityUser 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) 
    { 
     // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType 
     var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); 
     // Add custom user claims here 
     return userIdentity; 
    } 
} 

回答

2

使用简单的继承:

public class Business : ApplicationUser 
{ 
    ... 
} 

你会在你的AspNetUsers表中的列Discriminator,这将有助于实体框架的身份应该实例化的行(或BusinessApplicationUser)哪个阶级结束。然后,你可以只查询为正常,或者如果你只想要一个特定类型或另一个,你可以使用OfType<T>

var businessUsers = db.Users.OfType<Business>(); 

注意:默认情况下,实体框架处理简单的继承与一Discriminator列一个表。在大多数情况下,这很好,但你必须记住,你添加到你的基类的子类的任何属性必须是可空的。您不需要在数据库级别需要DateTime之类的Business,因为那样您永远不能保存ApplicationUser,而不是该属性。但是,这只是数据库级别的一个问题。从前端角度来看,您仍然可以使用视图模型制作Business所需的特定属性。

+1

如果我这样使用它,它会自动获取其他字段吗?因为我不想从AspNetUsers获得所有其他字段,只是其中的一部分。 – tett 2014-09-02 15:40:15

+0

是的,这是OOP 101,子类具有超类的所有属性。但是,再一次,仅仅因为它在那里,并不意味着你实际上必须*使用它。这就是为什么视图模型在良好的应用架构中如此重要。如果你真的不想要某些属性出现,你可以考虑创建类如'BusinessUser:ApplicationUser'和'NormalUser:ApplicationUser',这将允许你只放置这两种类型的用户共享的最基本的一组属性在'ApplicationUser'上,但请记住它们仍然会在同一个表中。 – 2014-09-02 15:48:34

+0

快速问题,我创建了两个类:Business:ApplicationUser和User:ApplicationUser,然后在我的IdentityModels文件中,我有这样的:public System.Data.Entity.DbSet Businesses {get ;组; }和用户模型的相同。然后我创建了一个迁移,但是当我执行Update-Database时,我收到一条错误消息,说“Table'aspnetusers'已经存在”。我怎么解决这个问题?应该首先删除我的数据库中的所有表,然后执行update-database? – tett 2014-09-04 16:44:08

相关问题