我正在使用Identity开发asp.net核心的Web应用程序。现在在我的应用程序中我有两种用户。客户和合作伙伴都有不同的个人资料信息和登录方案。客户可以从网页上的简单注册登录,但合作伙伴可以从不同的视图注册不同的必填字段。
这是我到目前为止所做的事情
public class ApplicationUser : IdentityUser
{
public CustomerProfile CustomerProfile { get; set; }
}
答案 0 :(得分:1)
使用继承:
public class ApplicationUser : IdentityUser {}
public class Customer : ApplicationUser
{
// Customer-specific properties
}
public class Partner : ApplicationUser
{
// Partner-specific properties
}
默认情况下,这将通过STI(单表继承)实现。这意味着您将只拥有标准的AspNetUsers表,其中包含ApplicationUser
和所有派生类型的属性列。将添加一个鉴别器列以指示实际保存的类型,然后将用于在查询时实例化正确的类型。
在大多数情况下,这很好用。一个缺点是派生类上的属性必须可以为空。原因很简单:在保存Customer
时,不可能为Partner
列提供值,反之亦然。但是,属性只需要在数据库级别可以为空。您仍然可以要求通过视图模型在表单中设置它们。
另一种方法是使用TPT(table-per-type)。使用这种方法,您将获得AspNetUsers,以及客户和合作伙伴表。但是,派生类型的表将具有仅对应于该类型特定属性的列和返回AspNetUsers的外键。所有常见属性都存储在那里。有了这个,您现在可以在数据库级别强制列具有值,但查询用户将需要连接。要使用TPT,只需将Table
属性添加到您的班级,即分别为[Table("Customers")]
和[Table("Partners")]
。
使用继承时要记住的一件重要事情是,您需要使用您实际想要保留的类型。如果您保存ApplicationUser
个实例,则该实例将是ApplicationUser
,而不是Customer
或Partner
。在这方面,您需要小心使用正确类型,例如UserManager
,它通常引用用户类型。即使您创建了Customer
的实例,如果您通过UserManager<ApplicationUser>
的实例进行保存,它也会转发为ApplicationUser
而 将保留的内容。要创建新的Customer
,您需要UserManager<Customer>
的实例。同样,对于合作伙伴。
但是,这也有利于您,就像您尝试从UserManager<Customer>
的实例中查找用户一样,如果它们实际上是Customer
,您将只能找到它们。通过这种方式,您可以轻松地拥有单独的门户网站,其中只有一个或另一个可以登录,因为您已经指出了您想要的内容。