为了账号安全,请及时绑定邮箱和手机立即绑定

当多个用户都扮演不同的角色时,我应该如何将它们存储在数据库中?

当多个用户都扮演不同的角色时,我应该如何将它们存储在数据库中?

C#
莫回无 2021-04-09 21:18:12
我正在创建一个具有四个用户的属性查看应用程序:Office Manager,Property Advisor,卖方和买方。我希望所有人都登录一次,但我不知道应该从哪里开始。我需要具有它们的ID,因为我正在将它们用于应用程序中的不同功能。例如,sellerId将链接到属性。一个BuyerId和PropertyAdvisorId将链接到一个约会。我想知道最好的方法是什么?
查看完整描述

1 回答

?
DIEA

TA贡献1820条经验 获得超2个赞

您是说您确实有四个用户或四种类型的用户吗?我认为是后者。


继承的用户

如果你的类型有很多共同点,如姓名,地址等,这将是最好有一个基本类型User,和几个派生类型:OfficeManager,PropertyAdvisor,等。


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


数据库不能很好地处理继承的概念,您必须使用一种变通方法来实现它。实体框架知道几种实现继承的策略。这里描述了其中几个


在您的情况下,最好使用“每类型表”:您将有一个Users表,并为派生类分别设置了一个Sellers表,一个Buyers表等。这些表中的每个表都具有该表的外键User。


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.

}

您需要告诉Entity Framework,您想要为用户/买方/卖方提供单独的表格。这可以使用属性来完成。我更喜欢使用流利的API:


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表,一个Rights表,一个用于Users和之间的多对多关系的联结表Rights,以及每个用户派生类一个单独的表,每个表都具有该Users表的外键。


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


关于表每种类型的好处是,如果你想查询的项目,所有的Users都有,就像一个名称/地址,只有一个查询表,无接缝是需要的,即使其中的一些Users是Buyers有的Sellers。另外,如果仅查询Buyer属性,则仅访问“买方”表。


缺点是,如果要查询“买方”属性及其“用户”属性,则需要“用户”与“买方”表之间的联接。


每种类型的表是否最适合您取决于您最常执行的查询类型。阅读所有描述的三种方法


组成方法

另一种方法不是使用继承,而是使用组合。这样,您的DbSet类将更好地描述您的表。其缺点是,它似乎有点怪你的DbContext的用户:Buyersdont't HAVE Users,他们Users,不是吗?


与其说卖方和买方是特殊类型的用户(继承),不如 说他们有用户UserInformation(组成)。这是一对一的关系。每个人UserInformation都有零个或多个权利(一对多)。


组成将导致与每个类型的表相同的表。唯一的区别是您的类更好地表示了您的表,但代价是您的类表示了您的直觉Sellers并且Buyers减少了Users的使用。


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;}

    ...

}

这将导致一个UserInformations表,一个Rights表,一个用于UserInformations和之间的多对多关系的联结表Rights,以及每个用户派生类一个单独的表,每个表都具有该Users表的外键。完全相同的表。


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


查看完整回答
反对 回复 2021-04-17
  • 1 回答
  • 0 关注
  • 268 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信