将不那么实体友好的遗留模式映射到实体

时间:2015-06-22 08:43:35

标签: c# sql linq entity-framework domain-driven-design

好的,我真的坚持这个。基本上我们在数据库中有一个遗留表(+规范化表),应该在不改变表模式的情况下创建真正的域实体。该表如下所示:

# identity table
| Domain (CK) | Group (CK) | Name (CK) | Password |
|-------------|------------|-----------|----------|
| root        |            |           |          |
| root        | group1     |           |          |
|             | group1     | someuser  | XXXXXX   |
|             | group2     |           |          |
|             |            | otheruser | XXXXXX   |

(CK = composite key)

旧应用程序强制执行以下规则:

  • 如果仅设置了Domain,则该实体是,可以包含用户和组
  • 如果仅设置了Group,则该实体是,可以包含用户
  • 如果设置了GroupDomain,则该实体是中的
  • 如果设置了Name,则该实体是相应中的用户(具体取决于设置的
  • 等。 (我希望你能得到这张照片)。

我们最终想要的是像这样的实体(伪):

class Domain {
    string Name;
    addUser(user);
    addGroup(group);
}

class Group {
    string Name;
    addUser(user);
}

class User {
    string Name;
    string Password;
}

我能想到解决这个问题的唯一两种方法是:

  • 创建所有三个标识类的基类,并创建包含标识符的第二个映射表。但那么:我怎么能告诉EF 鉴别器在不同的表中?我怎样才能执行业务规则,例如该表中包含GroupName的实体是User

  • 创建存储库以完成整个作业的映射和填充,并将每个业务规则表示为纯粹的应用程序逻辑,但是没有办法合并EF很酷的东西,如延迟加载,自动映射,LINQ等。我们基本上可以继续使用遗留代码。 ;)

具体问题:

  • 是否可以将鉴别器映射到EF中的其他表?
  • 是否有可能使该鉴别器不是一个值,而是有条件的? (例如 =&hasValue(Group) && !hasValue(Name)

1 个答案:

答案 0 :(得分:0)

有可能作弊,不要将它们视为完整的域实体。相反,您可以将用户管理视为具有自己的有界上下文的单独子域。使用反腐蚀层将BC与您域的其余部分隔离,该反腐蚀层将从该BC的语言翻译为通用域的语言。通常情况下,AC层将涉及从旧的,设计糟糕的类到新的DomainGroupUser类的映射器。

我认为这是开始从主域中的干净用户管理实体中受益的最明智的方式,同时保持选项开放以完全改造您的身份模块和数据库(这应该是我认为的最终目标)