我有以下应用程序结构,基于 Jeffery Palermo 的洋葱架构(参考链接)。所以我的核心不依赖于任何东西,我的基础设施依赖于我的核心
我的核心有存储库合同,我的基础设施实现了它。实现被我的 IoC 容器注入
Core
-Interfaces
--IRepository<TDomainModel>
-Domain
--Person
Infrastructure
-Data
--Repository<TDomainModel> (Implementation)
-Entities
--Ef.edmx
因此,如果我写出一个具体的存储库实现(例如 PersonRepository),这将不是问题,因为我也知道要投影/映射的类型。
示例具体实现:
public class PersonRepository
{
...
public IQueryable<PersonDomainClass> GetByName(string name)
{
return Dbcontext.Person.Where(x => x.name == name).Select(x => new Person());
}
...
}
我想要什么:
public class Repository<TDomainModel> : IRepository<TDomainModel>
{
//Problem 1. We can't set the DbSet to a Domain Model
private DbSet<TDomainModel> dbEntity;
...
public IQueryable<TDomainModel> GetWhere((Expression<Func<TDomainModel, bool>> predicate))
{
//Problem 2. I Don't think this will work because the predicate is ofType TDomainModel
//and not an EF Entity!?
var entities = dbEntity.Where(predicate);
var domainObjects = Mapper.Map <IQueryable<TDomainModel>, IQueryable<TEntityModel>> (entities);
return domainObjects;
}
...
}
我可能会以错误的方式解决这个问题,所以我打开了其他实现。
更新
好吧,谢谢大家的想法和建议。usr提出了一个我忽略的非常好的观点——如果我对我的 ORM 进行抽象,我将失去 ORM 提供的所有好处。
我正在使用 EF Database First 开发。所以我的实体与我的存储库实现一起在我的基础设施中。
域与此分开,因为我正在基于洋葱架构构建我的应用程序。
如果我在做 Code First,似乎要做的事情是先构建您的域,然后使用 EF Code 首先将其转换为数据库。
我不能先写代码:(
因此,EF 团队 @Microsoft 的实体框架 DbCotnext POCO 生成器分步进行。这会根据我的 edmx 文件生成持久的无知 POCO 类
到目前为止,这似乎很棒,我拥有延迟加载和更改跟踪的所有好处,甚至更好地为我生成了我的域,并且实体框架在内部处理映射。这简化了我的应用程序:)
所以这不是我的架构的高级视图
Core
-Interfaces
--IRepository<TEntity>
---IPersonRepository<Person>
---IFooRepository<Foo>
-Domain
--Person (Auto Generated)
--Foo (Auto Generated)
Infrastructure
-Data
--Repository<TEntity> (Implementation)
---PersonRepository<Person>
---FooRepository<Foo>
-Entities
--Ef.edmx