当多个用户具有不同的角色时,我应该如何将多个用户存储在数据库中?

时间:2018-04-12 16:37:11

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

我正在创建一个包含四个用户的属性查看应用程序:Office Manager,Property Advisor,Seller和Buyer。我宁愿为所有人登录,但我不知道应该从哪里开始。

我需要拥有他们的Id,因为我在应用程序中使用它们来实现不同的功能。例如,sellerId将链接到一个属性。 buyerId和PropertyAdvisorId将链接到约会。我想知道最好的办法是什么?

1 个答案:

答案 0 :(得分:1)

您的意思是说您真的有四个用户或四种类型的用户吗?我假设后者。

继承用户

如果您的类型有很多共同之处,例如姓名,地址等,最好有一个基本类型User和几种派生类型:OfficeManagerPropertyAdvisor等等。

每个User都有零个或多个Rights,每个Right都会被确认为零或更多Users:一个简单的多对多关系。

数据库不能很好地处理继承的概念,您必须使用解决方法来实现它。实体框架知道几种实现继承的策略。 Several of them are described here

在您的情况下,Table-Per-Type将是最好的:您将拥有一个Users表,以及派生类的单独表:Sellers表,{{{这些表中的每一个都将具有Buyers表的外键。

User

您需要告诉Entity Framework您需要为用户/买家/卖家分别使用表格。这可以使用Attributes完成。我更喜欢使用流畅的API:

abstract class User
{
    public int Id {get; set;}

    // every User has zero or more rights (many-to-many)
    public virtual ICollection<Right> Rights {get; set;}

    ... // other properties
}

class Seller : User
{
    // inherit primary key Id from base class
    ... // seller properties
}
class Buyer : User
{
    // inherit primary key Id from base class
    ... // buyer properties
}

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

    // every right is acknowledged to zero or more Users (many-to-many)
    public virtual ICollection<User> Users {get; set;}

    ... // properties that handle the rights.
}

这将导致public MyDbContext : DbContext { // The tables: public DbSet<Right> Rights {get; set;} public DbSet<User> Users {get; set; public DbSet<Seller> Sellers {get; set;} public DbSet<Buyer> Buyers {get; set;} ... protected override void OnModelCreating(DbModelBuilder modelBuilder) { // Buyers and Sellers are in separate tables: modelBuilder.Entity<Buyer>().ToTable("Buyers"); modelBuilder.Entity<Seller>().ToTable("Sellers"); // if you want you could name the User and Right tables // but that is not needed. Entity Framework already knows // they should be in separate tables modelBuilder.Entity<User>().ToTable("Users"); } } 表,Users表,RightsUsers之间多对多关系的联结表,以及一个单独的表每个用户派生类的表,每个表都带有Rights表的外键。

您是否注意到我将User类抽象化了?这是为了防止Users的用户添加DbContext。我们不知道User为对象,我们只知道UsersBuyers(等)

Table Per Type的优点在于,如果要查询所有Sellers所拥有的项,如名称/地址,则只查询一个表,不需要连接,即使其中一些{ {1}}为Users,有些为Users。此外,如果只查询Buyers属性,则只访问Buyer表。

缺点是,如果要查询买方属性及其用户属性,则需要在用户和买方表之间进行连接。

Table-Per-Type是否最适合您,取决于您最常做的查询类型。 Read all three described methods

组合方法

另一种方法是不使用继承,而是使用组合。这样,您的DbSet类将更好地描述您的表。缺点是你的DbContext用户似乎有点奇怪:Sellers不是Buyer,他们是Buyers,他们不是吗?

您可以说他们 Users(组合),而不是说卖家和买家特殊类型的用户(继承)。这是一对一的关系。每个Users都有零个或多个权限(一对多)。

组合将导致与每个类型的表相同的表。唯一的区别是,您的课程代表您的工作表更好,代价是您的课程代表您对UserInformationUserInformation用户较少的直觉感受。

Sellers

这将导致Buyers表,class UserInformation { public int Id {get; set;} public string FirstName {get; set;} public string MiddleName {get; set;} ... // every UserInformation has zero or more rights: (many-to-many) public virtual ICollection<Right> Rights {get; set;} } class Buyer { public int Id {get; set;} // Every Buyer has some UserInformation using foreign key (one-to-one) public int UserInformationId {get; set;} public virtual UserInformation UserInformation {get; set;} ... } class Seller { public int Id {get; set;} // Every Seller has some UserInformation using foreign key (one-to-one) public int UserInformationId {get; set;} public virtual UserInformation UserInformation {get; set;} ... } 表,UserInformationsRights之间多对多关系的联结表,以及一个单独的表每个用户派生类的表,每个都有UserInformations表的外键。完全相同的表格。

  

选择权在您自己:如果要将内部数据库结构隐藏到Rights的用户,请使用继承,如果要让数据库设计渗透到DbContext用户,请使用组合。