【问题标题】:How can I create two types of users in MVC5?如何在 MVC5 中创建两种类型的用户?
【发布时间】:2014-10-26 22:35:49
【问题描述】:

我正在创建 MVC5 应用程序,并且我已经在使用 ASP.NET Identity 来创建用户。所以,我已经有了 AspNetUsers 表,每当用户注册时,我都会在那里获得一个条目。我还有一个管理员角色,我在其中手动指定哪个注册用户是管理员。另一方面,我还需要注册企业,就像普通用户一样,他们将能够登录、注册和做一些事情。关键是他们将拥有一些与普通用户相似和不同的字段。例如,他们还会有电子邮件地址、密码(我想像普通用户一样对其进行哈希处理)、电子邮件确认、唯一 ID 等。但是他们有不同的字段来获取更多信息,比如他们的地址、zip ,国家,类别等普通用户没有的。如何在 MVC 中实现这一点?

我应该做一些类似于 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 的内容,例如 Email、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;
    }
}

【问题讨论】:

    标签: asp.net asp.net-mvc entity-framework


    【解决方案1】:

    使用简单继承:

    public class Business : ApplicationUser
    {
        ...
    }
    

    您最终会在 AspNetUsers 表中得到一个 Discriminator 列,这将有助于 Entity Framework 识别它应该为该行实例化哪个类(BusinessApplicationUser)。然后您可以正常查询,或者如果您只想要一种或另一种特定类型,您可以使用OfType&lt;T&gt;

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

    注意:默认情况下,Entity Framework 处理带有Discriminator 列的单个表的简单继承。在大多数情况下,这工作得很好,但您必须记住,您添加到基类的子类中的任何属性都必须是可空的。您不能在数据库级别要求Business 上的DateTime 之类的东西,因为那样您就永远无法保存ApplicationUser,它不具备该属性。但是,这只是数据库级别的问题。您仍然可以使用视图模型从前端角度创建 Business 上的特定属性。

    【讨论】:

    • 如果我这样使用它会自动获取其他字段吗?因为我不想从 AspNetUsers 中获取所有其他字段,只是其中的一些。
    • 是的,这是 OOP 101,子类具有超类的所有属性。但是,同样,仅仅因为它在那里,并不意味着你真的必须使用它。这就是为什么视图模型在良好的应用程序架构中如此重要的原因。如果您确实不希望出现某些属性,您可以考虑创建像 BusinessUser : ApplicationUserNormalUser : ApplicationUser 这样的类,这将允许您只将两种类型的用户共享的最基本的属性集放在 ApplicationUser ,但请记住,它们仍然会在同一张桌子上。
    • 快速提问,我创建了两个类:Business:ApplicationUser 和 User:ApplicationUser,然后在我的 IdentityModels 文件中,我有这样的内容:public System.Data.Entity.DbSet企业{得到;放; },与用户模型相同。然后我创建了一个迁移,但是当我更新数据库时,我收到一条错误消息,说“表'aspnetusers'已经存在”。我怎么解决这个问题?应该先删除我数据库中的所有表,然后再更新数据库?
    • 你可以试试。但是,如果您将UserDbSet 命名为Users,那么您将遇到IdentityDbContext 的问题。它已经为指定的用户类型实现了Users 属性,很可能是ApplicationUser。您需要为您的 User 集选择一个唯一的名称。
    • 好的,我把DbSet改成NormalUsers,或者我还需要改模型类的名字?
    猜你喜欢
    • 2023-01-21
    • 2021-12-02
    • 2017-04-07
    • 2020-07-27
    • 2016-12-02
    • 1970-01-01
    • 1970-01-01
    • 2014-03-01
    • 1970-01-01
    相关资源
    最近更新 更多