我一直在读Tim McCarthy的awesome book on DDD in .NET。但是在他的示例应用程序中,他的基础数据访问是使用SqlCE并且他手工编写SQL内联。
我一直在使用一些模式来利用Entity Framework,但我已经陷入了如何将IRepository linq查询映射到底层数据访问层的过程中。
我有一个名为。
的具体存储库实现public EFCustomerRepository : IRepository<DomainEntities.Customer>
{
IEnumerable<DomainEntities.Customer> GetAll(
Expression<Func<DomainEntities.Customer, bool>> predicate)
{
//Code to access the EF Datacontext goes here...
}
}
在我的EF模型中,我正在使用POCO实体,但即便如此,我的DomainEntity.Customer&amp;之间也没有原生映射。我的DataAccessLayer.Customer对象。
所以我不能只将Expression<Func<DomainEntities.Customer, bool>> predicate
作为EFContext.Customers.Where(...);
有没有简单的方法来映射
Expression<Func<T, bool>> predicate
=&gt; Expression<Func<TOTHER, bool>> predicate
或者我说这一切都错了? 任何建议/指示赞赏。
答案 0 :(得分:3)
在这种情况下,您必须将一个表达式树的自定义转换器实现为另一个表达式树(可能多于一个),这将完全涉及您的映射逻辑。通常,您的表达式目前只是规范(规范模式),您必须将该规范转换为存储表达式。
顺便说一下。这是错误的。不应该有单独的数据访问层对象 - 数据访问层应该直接加载和保存域对象,但EF不能完全正确地执行它,因为它的映射功能有限并且它将自己的需求推送到实体。如果你想认真做DDD(按书),你应该检查NHibernate或其他ORM。
答案 1 :(得分:2)
从您的示例中提供的代码中我猜您没有使用通用存储库模式?
我使用EF CodeFirst(但适用于旧版EF),使用通用存储库模式... http://average-uffe.blogspot.com/2011/03/repository-pattern-with-ef-code-first.html
我没有Expression<Func<DomainEntities.Customer, bool>>
在那篇文章中,我总是在IRepository<T>
界面中找到一个Find metod。
界面:
IEnumerable<T> Find(Expression<Func<T, bool>> expression, int maxHits = 100);
抽象baserepository中的实现:
public virtual IEnumerable<T> Find(Expression<Func<T, bool>> expression, int maxHits = 100) {
return this.DataContext.DbSet<T>().Where(expression).Take(maxHits);
}
现在你可以通过lambda表达式在任何实体上调用Find ...
如果你说不对,我可以发一个完整的例子,只是说什么时候。