我的存储库处理并为丰富的域模型提供持久性.我不想将贫血的Entity Framework数据实体暴露给我的业务层,所以我需要一些在它们之间进行映射的方法.
在大多数情况下,从数据实体构造域模型实例需要使用参数化构造函数和方法(因为它很丰富).它不像属性/字段匹配那么简单.AutoMapper可用于相反的情况(映射到数据实体),但不能用于创建域模型.
以下是我的存储库模式的核心.
在EntityFrameworkRepository类的工作有两个泛型类型:
TDomainModel:丰富的域模型TEntityModel:实体框架数据实体定义了两种抽象方法:
ToDataEntity(TDomainModel):转换为数据实体(for Add()和Update()方法)ToDomainModel(TEntityModel):构建域模型(用于Find()方法). 这些方法的具体实现将定义所讨论的存储库所需的映射.
public interface IRepository<T> where T : DomainModel
{
T Find(int id);
void Add(T item);
void Update(T item);
}
public abstract class EntityFrameworkRepository<TDomainModel, TEntityModel> : IRepository<TDomainModel>
where TDomainModel : DomainModel
where TEntityModel : EntityModel
{
public EntityFrameworkRepository(IUnitOfWork unitOfWork)
{
// ...
}
public virtual TDomainModel Find(int id)
{
var entity = context.Set<TEntityModel>().Find(id);
return ToDomainModel(entity);
}
public virtual void …Run Code Online (Sandbox Code Playgroud) .net domain-driven-design entity-framework repository-pattern onion-architecture
除了将关系数据转换为对象模型外,ORM还有其他角色,如:
- 延迟加载
- 自动更改检测
- 交易
但是,使用Repository模式将ORM的DTO转换为域模型时,会发生以下情况:
- 无法使用Lazy Load的好处,因为我需要填充我的整个域模型和存储库不知道域需要什么数据.
- ORM无法检测到更改,因为域模型不是来自ORM世界.
- 由于缺乏关于ORM的领域知识,不能再一次做很多交易
问题1:我是否遗漏了一些差距,我可以在域驱动设计方案中获得延迟加载,事务和自动更改检测的全部好处?或者这些好处更多是针对另一种方法(如Active Record)而不是DDD?
问题2:为什么在DDD书籍中提到了orm?仅针对域模型的关系和延迟加载,交易和变更检测完全放弃
有些平台采用代码优先方法,这是一种改善这些问题的方法,但是这个功能并不总是存在于许多环境中,或者根本无法使用(例如在遗留数据库中),因此它不是解决方案.
我第一次开始使用Entity Framework Code First,并且我们围绕域构建我们的绿地应用程序而不是关系数据库表(这是我多年来的工作方式)给我留下了深刻的印象.
因此,我们正在构建C#中的实体,每次我们进行新的迁移时都会反映在数据库中.
我的问题是:这些相同的实体(即设计时考虑到实体框架)是否应该与域驱动设计中的实体扮演相同的角色(即代表域的核心)?
我目前正在学习开发领域的设计方法,并使用Tim McCarthy的.NET域驱动设计和C#书作为指南.
这本书真的很有帮助,但在使用实体框架时,我变得有点不安,特别是4.1中提供的代码优先方法.
根据本书中的示例,分层体系结构方法应该意味着基础结构层无法看到模型/域.
那么在db上下文类中映射我的域poco的最佳方法是什么(我假设)应该位于基础结构层中,而不会违反分层方法?
很有可能我的想法完全错了所以请告诉我,因为我还在学习!
非常感谢 :)
亚当