是否有在基于 DDD 的分层架构中的模型和数据访问层之间使用 LINQ 的建议模式

Posted

技术标签:

【中文标题】是否有在基于 DDD 的分层架构中的模型和数据访问层之间使用 LINQ 的建议模式【英文标题】:Is there a suggested pattern for using LINQ between the Model & DataAccess Layers in a DDD based Layered Architecture 【发布时间】:2011-10-24 02:02:32 【问题描述】:

我一直在阅读 Tim McCarthy 的 awesome book on DDD in .NET。不过,在他的示例应用程序中,他的底层数据访问使用的是 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&lt;Func&lt;DomainEntities.Customer, bool&gt;&gt; predicate 作为EFContext.Customers.Where(...); 的参数

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

或者我做错了? 任何建议/指针表示赞赏。

【问题讨论】:

这本书是否建议你使用领域对象数据层对象?这似乎是多余的,尤其是因为您使用 POCO 实体。 AFAIK 围绕 DDD 的整个想法是对域进行单一定义,并允许在整个应用程序中使用它。 【参考方案1】:

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

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

【讨论】:

谢谢,很好的意见!但我仍然想知道如何使用 Exrepssion 编写 AST 转换?你能提供一些好的例子、开源项目或书籍来阅读吗?我真的需要它来快速实现它:)【参考方案2】:

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

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

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

界面:

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

如果你不明白,我可以发布一个完整的例子,只是说什么时候。

【讨论】:

以上是关于是否有在基于 DDD 的分层架构中的模型和数据访问层之间使用 LINQ 的建议模式的主要内容,如果未能解决你的问题,请参考以下文章

DDD的分层架构设计

DDD—分层架构洋葱架构六边形架构

解构领域驱动设计:领域驱动设计的核心之分层架构

基于DDD的ABP开发框架 - ABP分层设计

还在搞三层架构?DDD 分层架构了解下!

DDD「领域驱动设计」分层架构初探