我的存储库处理并为富域模型提供持久性。我不想将贫血的实体框架数据实体暴露给我的业务层,因此我需要某种方式在它们之间进行映射。
在大多数情况下,从数据实体构造域模型实例需要使用参数化的构造函数和方法(因为它很丰富)。它不像属性/字段匹配那么简单。AutoMapper 可用于相反的情况(映射到数据实体),但不能用于创建域模型。
下面是我的存储库模式的核心。
该类EntityFrameworkRepository
适用于两种通用类型:
TDomainModel
: 富域模型TEntityModel
: Entity Framework 数据实体
定义了两个抽象方法:
ToDataEntity(TDomainModel)
: 转换为数据实体(forAdd()
和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 Add(TDomainModel item)
{
context.Set<TEntityModel>().Add(ToDataEntity(item));
}
public virtual void Update(TDomainModel item)
{
var entity = ToDataEntity(item);
DbEntityEntry dbEntityEntry = context.Entry<TEntityModel>(entity);
if (dbEntityEntry.State == EntityState.Detached)
{
context.Set<TEntityModel>().Attach(entity);
dbEntityEntry.State = EntityState.Modified;
}
}
protected abstract TEntityModel ToDataEntity(TDomainModel domainModel);
protected abstract TDomainModel ToDomainModel(TEntityModel dataEntity);
}
这是存储库实现的基本示例:
public interface ICompanyRepository : IRepository<Company>
{
// Any specific methods could be included here
}
public class CompanyRepository : EntityFrameworkRepository<Company, CompanyTableEntity>, ICompanyRepository
{
protected CompanyTableEntity ToDataEntity(Company domainModel)
{
return new CompanyTable()
{
Name = domainModel.Name,
City = domainModel.City
IsActive = domainModel.IsActive
};
}
protected Company ToDomainModel(CompanyTableEntity dataEntity)
{
return new Company(dataEntity.Name, dataEntity.IsActive)
{
City = dataEntity.City
}
}
}
问题:
ACompany
可能由许多Departments
. 如果我想CompanyRepository
在获取 a 时急切地加载这些,Company
那么我将在哪里定义 aDepartment
和 a之间的映射DepartmentDataEntity
?
我可以在 中提供更多映射方法CompanyRepository
,但这很快就会变得混乱。很快就会在整个系统中出现重复的映射方法。
解决上述问题的更好方法是什么?