0

我一直在反复讨论两种做事的方式,但无法解决我认为更好的方式(或者看看为什么我可能会以错误的方式去做)。

我为 3 种不同类型的用户提供了 3 个不同的网站,但它们共同构成了整个系统。例如,员工的管理门户、客户的客户门户和供应商的供应商门户。在这里,我将这些不同的实体表示为“域”。

每个域都有自己的一组用户和一组角色 - 因为每个门户的业务性质是不同的,所以用户和每个门户中的关联角色也是不同的(例如,一个门户有报告,另一个没有't,因此一个门户具有“报告”角色)。

我没有包括将 User 子类型化为“StaffUser”的事实,因为它具有字段和对普通用户不需要的其他表的引用(例如 Team、Department 等)。

-----------------             -----------------
| Domain        |             | Role          |
-----------------  <--------- -----------------
| DomainId (PK) |             | RoleId (PK)   |
|               |             | DomainId (FK) |
-----------------             -----------------
        >                              >
        |                              |
        |                              |
        |                              |
-----------------             -----------------
| User          |             | User_Role     |
-----------------  <-------   -----------------
| UserId (PK)   |             | UserId (PK)   |
| DomainId (FK) |             | RoleId (PK)   |
-----------------             -----------------

在上面的示例中,我可以有n 个域,每个域有n 个用户和n 个角色,并且用户可以与角色相关联。4张表,非常简单,每样东西都有一个判别器值。

在我的 Web 应用程序中(为了论证,我使用 .NET MVC 和 Entity Framework),当我希望为用户分配角色时,我选择与用户具有相同域类型的所有角色,并保存我想要的配对。

但是,如果在选择域的代码的生成过程中出现某种错误(有人在域类型上使用了错误的枚举),那么现在我们突然将一种域类型的用户与另一种域类型的角色进行匹配。 . 混乱随之而来。

这种情况如何预防?可以在 SQL 中强制执行吗?我在担心不太可能发生的事情吗?我见过比我那个时代更荒谬的 SNAFU。

那么,如果我将一个 table-per 结构带入其中会怎样:

-----------------
| Domain        |
-----------------
| DomainId (PK) |
-----------------
        >
        |
        |
        |
-----------------             ------------ ----            ---------------
| DomainA       |             | DomainARole   |            | Role        |
------------ ----  <--------  -----------------  --------> ---------------
| DomainId (PK) |             | RoleId (PK)   |            | RoleId (PK) |
|               |             | DomainId (FK) |            |             |
-----------------             -----------------            ---------------
        >                              >
        |                              |
        |                              |
        |                              |
----------------              ---------------------------
| DomainAUser  |              | DomainAUser_DomainARole |
----------------   <-------   --------------------------|           
| UserId (PK)  |              | UserId (PK)             |
| DomainId (FK)|              | RoleId (PK)             |
----------------              ---------------------------
        |
        |
        |
        >
----------------
| User         |
----------------
| UserId (PK)  |
----------------

在本例中,DomainARole 继承自 Role,DomainAUser 继承自 User。如果我们想添加更多域,我们需要为每种类型创建一个新表,并且可能有很多表(在我的情况下,无论如何“域”不会超过 3 个)。这是不必要的过度复杂化吗?

第一个好处是 DomainAUser 只能有一个 DomainARole ......它是在引用那里强制执行的。我再也不用担心将两对与鉴别器匹配了,因为所有东西都整齐地分开成表格。

第二个好处是,如果将来需求发生变化(DomainAUser 需要 DomainBUser 不需要的额外字段),我已经准备好表格并且它很灵活。

我是否错过了一种更简单的方法来解决这个问题?目前我一直支持第二个,更重表的版本。

有没有办法使用鉴别器强制执行我需要的约束?我把事情复杂化了吗?我真的无法决定。

4

1 回答 1

0

不要为此使用继承。当您想将“普通”用户转变为管理员时会发生什么?(或者客户变成供应商,等等?)你不能,因为对象不能改变它们的类型。你留下了丑陋的选择,比如删除和重新创建用户。如果一个用户在两个域中工作怎么办?继承根本无法支持这一点。

有时人们试图声称在他们的系统中这永远不会发生,但在现实世界中它确实发生了,而继承在这里实际上并没有给你带来太多好处。为什么要付出使用它的代价?

相反,您应该使“DomainAUser”信息成为一个单独的表,并具有从 User 到 DomainAUser 的关联/导航,因此会有一个User.DomainA属性,对于非 DomainA 用户,该属性将为 null。

于 2012-08-15T11:49:58.017 回答