除了将关系数据转换为对象模型外,ORM还有其他角色,如:
延迟加载
自动更改检测
交易
但是,使用Repository模式将ORM的DTO转换为域模型时,会发生以下情况:
无法使用Lazy Load的好处,因为我需要填充我的整个域模型和存储库不知道域需要什么数据.
ORM无法检测到更改,因为域模型不是来自ORM世界.
由于缺乏关于ORM的领域知识,不能再一次做很多交易
问题1:我是否遗漏了一些差距,我可以在域驱动设计方案中获得延迟加载,事务和自动更改检测的全部好处?或者这些好处更多是针对另一种方法(如Active Record)而不是DDD?
问题2:为什么在DDD书籍中提到了orm?仅针对域模型的关系和延迟加载,交易和变更检测完全放弃
有些平台采用代码优先方法,这是一种改善这些问题的方法,但是这个功能并不总是存在于许多环境中,或者根本无法使用(例如在遗留数据库中),因此它不是解决方案.
我一直在想,如果要从ORM中删除更改跟踪,那么开发人员会看到它们的价值远低于此.
懒惰应该永远不会发生.总是加载聚合.如果您发现自己需要延迟加载,则可能是您正在查询域模型.这是你不应该做的事情.使用简单的查询图层/读取模型.
事务确实是数据库关注的问题,不会直接影响DDD.聚合确实代表了一致性边界,因此数据库事务很自然,但它就是它的结束点.
您仍然可以使用带DDD的ORM工具,但您可能会获得更少的里程数.我根本不喜欢ORM,如果我有任何选择,我根本就不使用它们.映射实际上并不是那么多工作,如果在自定义映射器类中完成,则以语言速度运行而不是某些代理机制.
有些实例我已经看到域对象的位置,例如,使用ORM直接持久化.但是,如果我必须使用某个属性标记任何内容,甚至更改我的设计,我必须实现某些方法,virtual
甚至以特定的方式构造某些类,我不再认为我的域是持久的无知,这就是我真的想要(PI).
但是,使用存储库模式将ORM的DTO转换为域模型时,会发生以下情况:
无法使用延迟加载的好处,因为我需要填充整个域模型,并且存储库不知道域需要什么数据。
由于域模型不是来自ORM世界,所以ORM无法检测到更改。
再次,由于缺乏有关ORM的域知识,无法一次执行许多事务
使用现代ORM时,无需实现将ORM的实体映射到域实体的另一层。在.NET世界中,无论是Entity Framework还是NHiberate都能将您的Rich Domain Model映射到关系数据库中。
两者都可以使用“代码优先”方法。
首先设计域模型,然后使用映射(实体框架Fluent Api / Fluent NHibernate映射)或约定(EF自定义代码优先约定 / Fluent NHibernate自动映射)生成数据库
有一些相关的SO问题:
有关将实体映射到域对象的建议
存储库模式以及域模型与实体框架之间的映射