【发布时间】:2011-06-27 17:40:31
【问题描述】:
似乎在 DDD、存储库、数据映射器等周围有很多“噪音”……而很少有“真实世界”实现代码向像我这样的新手展示什么是“好”,什么是“好” “坏”。
我刚刚读完Architecting Applications for the Enterprise 这本书,让我大开眼界。我目前在工作项目中使用 Active Record 模式,并且一直在努力将其更改为使用域模型。我使用了本书中的大量架构示例,以及本书随附的 Northwind Starter Kit 代码下载。
一切都很顺利,但现在我遇到了我的第一个“现实世界”数据映射器问题……也就是说,我的映射器不仅仅负责获取一个实体对象并将其持久化到数据库中,我现在有一个 Entity 对象,该对象有一个 IList 集合,该集合也需要映射。
主要的Entity对象是Expert,代码如下:
public class Expert
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual IList<Case> Cases { get; protected set; }
}
这里是来自 Expert 的集合的实现,即 Case 对象:
public class Case
{
public int ID { get; set; }
public string Name { get; set; }
}
没有比这更简单的了。
现在,每个实体项都有一个 DataMapper,但我的问题是,当我在 ExpertDataMapper 代码中映射 Case 集合时,什么被认为是“正确”的方法?
在本书中,ExpertDataMapper 中嵌入了实际的 SQL 代码,该代码调用了 ADO.NET 代码,该代码获取 IList 集合中的所有 Case 项目,并为每个项目调用一次该代码。这是一些伪代码:
public virtual void Create(Expert expert)
{
// Insert expert in the Expert table
SqlHelper.ExecuteNonQuery(ProviderHelper.ConnectionString, CommandType.Text,
"SQL TO INSERT EXPERT", this.BuildParamsFromEntity(expert));
// Insert individual Case items in the Case table
foreach (Case c in expert.Cases)
{
SqlHelper.ExecuteNonQuery(ProviderHelper.ConnectionString, CommandType.Text,
"SQL TO INSERT CASE", this.BuildParamsFromEntity(order));
}
}
所以这有两点不对劲:
- 为什么 ExpertDataMapper 有 SQL 调用(或存储的 proc 调用)来插入嵌入自身的 Case?对我来说,这打破了封装的想法...... ExpertDataMapper 不应该知道如何将 Case 插入数据库,这就是 CaseDataMapper 的工作。
我认为 ExpertDatMapper 应该将插入 Case 的任务委托给 CaseDataMapper...但我不知道一个 DataMapper 实例化另一个 DataMapper 是“正确”还是“错误”。这被认为是 DataMappers 的常规问题吗?我找不到关于这个问题的指导,我认为这是相当普遍的。
- 如果我有 100 个案例与此专家相关联,那就是创建了 100 个案例对象,以及针对数据库的 100 个插入语句?这件事让我感觉“不对”,违背了我更好的判断。现在,如果我有幸能够使用 SQL Server 2008,我可以使用表值参数,它不会那么糟糕,但我们现在是 2005 年。
所以,当谈到 DataMappers 时,我还没有看到在实体对象的 DataMaper 上使用简单的集合关联进行简单创建、更新等的任何具体实现。我正在阅读的书没有支持它的代码(而且那里的代码对我来说看起来很可疑)。
我已经阅读并拥有 Martin Fowler 的 P of EAA 书,所以请不要让我看那里。我也知道我可以使用的 ORM 工具,所以我不需要自己负责实现 DAL。我玩过 EF 4.0,我喜欢它。但是对于这个项目,我没有使用 ORM 工具的选项。
大多数书籍/示例似乎都停留在相同的基本前提上,即只要我的 Entity 对象与通过 DataMapper 持久化到的表之间存在一对一关联,世界就是玫瑰色的使用领域模型方法...
如果我的所有实体都是一对一的,我还不如只使用 Active Record 并完成它。
有任何指导、建议和见解吗?抱歉,这是一篇很长的帖子,但我在这里阅读了其他类似问题的帖子,但没有关于如何处理此处提出的问题的真正具体答案或建议。
【问题讨论】:
标签: activerecord domain-driven-design data-access-layer repository-pattern datamapper