将实体不太友好的遗留模式映射到实体
Mapping not-so-entity-friendly legacy schema to entities
好吧,我真的坚持这个。基本上,我们的数据库中有一个遗留 table(+ 规范化 tables),应该在不改变 table 模式的情况下从中创建真正的域实体。 table 看起来像这样:
# identity table
| Domain (CK) | Group (CK) | Name (CK) | Password |
|-------------|------------|-----------|----------|
| root | | | |
| root | group1 | | |
| | group1 | someuser | XXXXXX |
| | group2 | | |
| | | otheruser | XXXXXX |
(CK = composite key)
旧应用程序强制执行以下规则:
- 如果只设置了
Domain
,则实体是一个域,可以包含用户和组
- 如果只设置
Group
,则实体是一个组,可以包含用户
- 如果设置了
Group
和 Domain
,实体是 domain[= 中的 group 59=]
- 如果设置了
Name
,则实体是相应 组 或 域 中的用户(取决于哪个已设置)
- 等(我希望你明白这张照片)。
我们最终想要的是这样的实体(伪):
class Domain {
string Name;
addUser(user);
addGroup(group);
}
class Group {
string Name;
addUser(user);
}
class User {
string Name;
string Password;
}
我能想到的解决此问题的唯一两种方法是:
创建所有三个身份 class 的基础 class 并创建第二个映射 table 包含 鉴别器 。但是然后:我怎么能告诉 EF discriminator 在不同的 table 中?以及我如何执行业务规则,例如table 中同时具有 Group
和 Name
的实体是 User
?
创建存储库来完成映射和其他工作,并将每个业务规则表示为纯应用程序逻辑,但这样就无法合并 EF 等很酷的东西,例如延迟加载、自动映射、 LINQ 等,我们基本上可以继续使用我们的遗留代码。 ;)
具体问题:
- 是否可以在 EF 中将 鉴别器 映射到不同的 table?
- 是否可以使该鉴别器不是一个值,而是一个条件? (例如组的鉴别器=>
hasValue(Group) && !hasValue(Name)
可以稍微作弊而不将它们视为成熟的域实体。相反,您可以将用户管理视为具有自己的限界上下文的单独子域。使用反腐败层将 BC 与域的其余部分隔离开来,该反腐败层将此 BC 的语言转换为通用域的语言。通常,AC 层将涉及从旧的、设计糟糕的 类 到新的 Domain
、Group
和 User
类.
的映射器
我认为这是最明智的方式,可以立即开始从您的主域中干净的用户管理实体中获益,同时保持对您的身份模块和数据库进行彻底改造的选项开放(我想这应该是最终的目标)。
好吧,我真的坚持这个。基本上,我们的数据库中有一个遗留 table(+ 规范化 tables),应该在不改变 table 模式的情况下从中创建真正的域实体。 table 看起来像这样:
# identity table
| Domain (CK) | Group (CK) | Name (CK) | Password |
|-------------|------------|-----------|----------|
| root | | | |
| root | group1 | | |
| | group1 | someuser | XXXXXX |
| | group2 | | |
| | | otheruser | XXXXXX |
(CK = composite key)
旧应用程序强制执行以下规则:
- 如果只设置了
Domain
,则实体是一个域,可以包含用户和组 - 如果只设置
Group
,则实体是一个组,可以包含用户 - 如果设置了
Group
和Domain
,实体是 domain[= 中的 group 59=] - 如果设置了
Name
,则实体是相应 组 或 域 中的用户(取决于哪个已设置) - 等(我希望你明白这张照片)。
我们最终想要的是这样的实体(伪):
class Domain {
string Name;
addUser(user);
addGroup(group);
}
class Group {
string Name;
addUser(user);
}
class User {
string Name;
string Password;
}
我能想到的解决此问题的唯一两种方法是:
创建所有三个身份 class 的基础 class 并创建第二个映射 table 包含 鉴别器 。但是然后:我怎么能告诉 EF discriminator 在不同的 table 中?以及我如何执行业务规则,例如table 中同时具有
Group
和Name
的实体是User
?创建存储库来完成映射和其他工作,并将每个业务规则表示为纯应用程序逻辑,但这样就无法合并 EF 等很酷的东西,例如延迟加载、自动映射、 LINQ 等,我们基本上可以继续使用我们的遗留代码。 ;)
具体问题:
- 是否可以在 EF 中将 鉴别器 映射到不同的 table?
- 是否可以使该鉴别器不是一个值,而是一个条件? (例如组的鉴别器=>
hasValue(Group) && !hasValue(Name)
可以稍微作弊而不将它们视为成熟的域实体。相反,您可以将用户管理视为具有自己的限界上下文的单独子域。使用反腐败层将 BC 与域的其余部分隔离开来,该反腐败层将此 BC 的语言转换为通用域的语言。通常,AC 层将涉及从旧的、设计糟糕的 类 到新的 Domain
、Group
和 User
类.
我认为这是最明智的方式,可以立即开始从您的主域中干净的用户管理实体中获益,同时保持对您的身份模块和数据库进行彻底改造的选项开放(我想这应该是最终的目标)。