以下是通过Entity Framework 6 Fluent API直接映射到数据库的 Project 代码优先类:
public class Project
{
public Project()
{}
public int ProjectId { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
public ICollection<ProjectVersion> ProjectVersions { get; set; }
}
域驱动设计中的贫血模型是一种反模式。我想在我的域模型中使用同一个类,而不是创建一个单独的Project
域类,并且必须在存储库中的两个之间执行复杂的映射(以及其他数百个模型我们有)。
这就是Project
看起来像域模型类的方式:
public class Project
{
private readonly List<ProjectVersion> projectVersions;
public Project(string name, string description)
{
Name = name;
Description = description;
projectVersions = new List<ProjectVersion>();
}
public int ProjectId { get; private set; }
public string Name { get; set; }
public bool IsActive { get; private set; }
public IEnumerable<ProjectVersion> ProjectVersions
{
get
{
return projectVersions;
}
}
public void AddVersion(ProjectVersion version)
{
projectVersions.Add(version);
}
}
From what I have read,我可以使用EF的Fluent API映射到私有字段。
这里有什么缺点吗?我是否采取了不必要的捷径?
我可以预见的唯一问题是,业务领域模型基本上由来自两个或多个数据实体的数据组成。
答案 0 :(得分:2)
我认为你在这种方法上犯了一个错误。我认为您应该将您的域模型的关注点与您的实体模型的关注点分开。鲍勃叔叔写了一篇关于此的奇怪但有点博客文章:Dance You Imps!(严肃地说,这是一个奇怪的帖子。)ORM的工作是作为你的数据库的合同。您的域模型的工作是提供功能。简而言之,您应该让Entity Framework以其想要的方式运行。如果要进行DDD,请编写映射层以将EF模型转换为域模型。
答案 1 :(得分:1)
这里有任何缺点吗?
可能。
EF确实可以解决私有成员问题,因此如果您愿意,可以使用加载的Project
集合实现ProjectVersions
。它不会使用AddVersion
方法(它甚至不知道它存在),但它会将对象添加到projectVersions
成员。
在应用程序代码中,您希望通过方法添加版本。但这种AddVersion
方法可能存在一些问题。
ProjectVersion
,但您永远不会确定是否会将其存储,因为要跟踪EF,必须加载projectVersions
。但是,您不希望域实体负责从数据库加载自己的子项。所以AddVersion
给了班级一个无法满足的责任。AddVersion
。通常这将比创建和跟踪它的上下文的生命周期长。因此,如果尚未加载集合,则不能依赖延迟加载来解决问题。 (顺便说一下,ProjectVersions
应该virtual ICollection
。projectVersions
急切地(通过Include
)加载AddVersion
才能保证正常运行。因此,您的应用程序之间存在两个不明显相关的代码片段之间的依赖关系,这可能是错误的来源。Project
时,您必须将其附加到上下文,并找出哪个ProjectVersion
应该标记为插入,哪个用于更新(甚至没有RemoveVersion
1}}方法。总而言之,在服务方法中添加版本更简单,该方法在上下文的生命周期内执行所有必需的操作。添加的版本将被标记为自动插入。同样,任何更新和删除的版本都将被正确标记。