我一直在两种方式来回打击,并且无法解决我认为更好的问题(或者看看为什么我可能会采用错误的方式)。
我为3种不同类型的用户提供了3个不同的网站,但它们共同构成了整个系统。例如,员工的管理员门户,客户的客户门户和供应商的供应商门户。在这里,我将这些不同的实体表示为“域”。
每个域都有自己的一组用户和自己的一组角色 - 因为每个门户的业务性质是不同的,用户也是如此,每个门户中的相关角色也是如此(例如,一个门户有报告,另一个没有,所以一个门户网站有“报告”角色。)
我没有包含这样一个事实,即我将User off子类型化为“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),当我希望为用户分配角色时,我选择与用户相同的Domain类型的所有角色,并保存配对我想要。
但是,如果在选择域的代码生成中出现某种问题(有人在域类型上使用了错误的枚举),现在我们突然将一个域类型的用户与另一个域的角色进行匹配类型......混乱随之而来。
这种情况如何可以预防?可以在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继承自User的Domain,DomainAUser inherts。如果我们想要添加更多域,我们需要为每种类型添加一个新表,这可能是很多表(在我的情况下,不管怎样,其中不会有超过3个“域”)。这是不必要的过度复杂吗?
第一个好处是DomainAUser只能拥有一个DomainARole ......它在那里被引用。我再也不用担心将两对与鉴别器相匹配,因为一切都整齐地分成了几个表。
第二个好处是,未来需求会发生变化(DomainAUser需要DomainBUser不需要的额外字段)我有适当的表格并且它很灵活。
我错过了一种简单的方法来解决这个问题吗?目前我一直赞成第二个更重的桌面版本。
有没有办法使用鉴别器来强制执行我需要的约束?我是不是太复杂了?我真的无法决定。
答案 0 :(得分:0)
不要为此使用继承。当您想要将“常规”用户变为管理员时会发生什么? (或者客户进入供应商等?)你不能,因为对象不能改变他们的类型。你留下了丑陋的选择,比如删除和重新创建用户。如果一个用户在两个域中工作怎么办?继承不能支持这一点。
有时候人们会试图在他们的系统中声称这种情况从未发生过,但在现实世界中它确实如此,而继承实际上并不会在这里给你带来太大的影响。为什么要付出使用价格?
相反,您应该将“DomainAUser”信息设置为一个单独的表,并具有从User到DomainAUser的关联/导航,因此将存在User.DomainA
属性,对于非DomainA用户将为null。