7

我一直在阅读 Tim McCarthy关于 .NET 中 DDD 的精彩书籍。不过,在他的示例应用程序中,他的底层数据访问使用的是 SqlCE,并且他正在手工制作 SQL 内联。

我一直在玩一些利用实体框架的模式,但我一直坚持如何将 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 和我的 DataAccessLayer.Customer 对象之间也不会存在本机映射。

所以我不能只Expression<Func<DomainEntities.Customer, bool>> predicate作为参数传递EFContext.Customers.Where(...);

有没有一种简单的方法来映射 Expression<Func<T, bool>> predicate=>Expression<Func<TOTHER, bool>> predicate

还是我要说这一切都错了?任何建议/指针表示赞赏。

4

2 回答 2

3

在这种情况下,您必须实现一个表达式树到另一个表达式树的自定义转换器(可能不止一个),这将完全涉及您的映射逻辑。通常,您的表达式目前只是规范(规范模式),您必须将该规范转换为存储表达式。

顺便提一句。这是错误的。不应有单独的数据访问层对象 - 数据访问层应直接加载和保存您的域对象,但 EF 并不能完全正确地执行此操作,因为它的映射功能有限,并且它将自己的需求推送到实体。如果你想认真地做 DDD,你应该检查 NHibernate 或其他 ORM(按书)。

于 2011-08-10T13:48:14.787 回答
2

从您的示例中提供的代码中,我猜您没有使用通用存储库模式?

我使用带有通用存储库模式的 EF CodeFirst(但它适用于旧 EF)... http://average-uffe.blogspot.com/2011/03/repository-pattern-with-ef-code-first.html

我在那篇文章中没有,但我总是在界面Expression<Func<DomainEntities.Customer, bool>> 中有一个 Find 方法。IRepository<T>

界面:

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 ...

如果您不正确,我可以发布一个完整的示例,只需说明何时。

于 2011-08-14T19:30:36.253 回答