我目前正在研究我们下一个项目的体系结构和模式。我正在考虑使用DDD,但由于该项目规模中等,我试图从代码重复和整体维护的角度尽可能简化它。DDD,实体框架和实体映射
各层如下所示,基本上每个层是一个单独的组件:
DB -> Domain -> Application -> Web API -> Clients
对于DB访问我使用EF核心1.0。
这是我目前设计(简化)的数据和域图层中的类,我对此并不满意。
域:
class Task
{
private int State { get; set; }
private string Description { get; set; }
private int CreatedById { get; set; }
}
数据(EF):
class TaskData
{
public int State { get; set; }
public string Description { get; set; }
public int CreatedById { get; set; }
public User CreatedBy { get; set; }
}
理想情况下,我想直接与ORM使用我的域实体,但任务和TaskData是不相同的。在任务实体中,我不需要导航属性CreatedBy,我很好,只是一个Id,所以我不想污染与它不关心的东西的域。
在数据模型中,我对某些报告使用了导航属性,因此在某些情况下此连接很有用。如你所见,如果我不能直接映射域实体,我必须在数据层做一些映射。更具体地说,在存储库通过。手动映射器类。由于我的域实体没有公共getter和setter,因此我无法将TaskData映射到属性基础上的Task实体。
这使我Memento模式,所以我创造新的类,它似乎只是简单的DTO:
class TaskSnapshot
{
public int State { get; set; }
public string Description { get; set; }
public int CreatedById { get; set; }
}
而且我原来的工作单位看起来像现在这样:
class Task
{
...
public Task(TaskSnapshot snapshot)
{
this.State = snapshot.State;
this.Description = snapshot.Description;
this.CreateById = snapshot.CreatedById;
}
public TaskSnapshot ToSnapshot()
{
return new TaskSnapshot()
{
State = this.State,
Description = this.Description,
CreatedBy = this.CreatedBy };
}
}
正如你可以看到,它需要三个不同目的的课程,但是要创建和维护的内容非常相似。它只是数据和领域层。 “重复”也在其他层次上继续。
现在,当我决定添加一个新字段时,我需要记住添加它的所有位置以及正确赋值。我担心这往往会导致错误,因为团队中的某个人只是忘记更新所有代码。
我可以做什么:
制作getter和setter域上的实体公开,这样我就不需要快照。 - >绝对没有!
将不必要的属性(CreatedBy导航)添加到Task实体,并直接在ORM中使用它。 - >我宁可不要。
将快照类转换为数据模型并将它们与ORM结合使用。 - >我可能不介意那里的导航属性,但这意味着数据模型是域程序集的一部分。 - >我不知道,我不喜欢它。
有一个建议,我怎么能有效地减少班级人数或集中ALL的分配(映射)到一个地方/映射类不影响域?
谢谢。
只是一个问题 - 为什么不先使用代码?这样您可以直接将数据库映射到您的域图层。 –
我先使用代码,但在我的数据模型中,我需要定义导航属性,这在域实体中并不需要。所以这两个模型是不一样的。 –
这里有几个策略:vaughnvernon.co/?p=879 – jlvaquero