是否有在基于 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<Func<DomainEntities.Customer, bool>> predicate
作为EFContext.Customers.Where(...);
的参数
有没有一种简单的方法来映射
Expression<Func<T, bool>> predicate
=> Expression<Func<TOTHER, bool>> 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<Func<DomainEntities.Customer, bool>>
在那篇文章中,但我总是在 IRepository<T>
界面中有一个 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 的建议模式的主要内容,如果未能解决你的问题,请参考以下文章