2012-02-08 80 views
3

我正在尝试构建一个解耦域模型。我的(抽象)域模型定义了一个实体,例如“Product”,然后我的具体SQL实现为该实体提供了一个转换方法。转换Linq表达式的基类

例如:

public interface IDomainEntity<T> where T : class 
{ 
    T ToDomainEntity(); 
} 

我具体的SQL类,那么实现该接口:

public partial class Product : IDomainEntity<Domain.Product> 
{ 
    public Domain.Product ToDomainEntity() 
    { 
     return new Domain.Product 
     { 
      ProductId = this.ProductId, 
      ... 
     }; 
    } 
} 

从我的产品领域的服务,我希望能够揭露一般的过滤方法

public virtual IQueryable<T> Filter(Expression<Func<T, bool>> predicate) 
{ 
    return GetAll().Where(predicate); 
} 

在这种情况下,T的类型是Domain.Product。我遇到的问题是,在SQL存储库实现中,我需要将表达式从Domain.Product类型转换为Sql.Product类型,以便我可以将它用于我的Linq to Sql表。

是否有可能采取一个表达的基础,并将其转换为另一种:

Expression<Func<Domain.Product, bool>> 

Expression<Func<Sql.Product, bool>> 

道歉提前如果这没有意义。

回答

2

即使你想要做什么是可能的,真正的问题应该是:会什么做这个来得到什么呢?

在我看来,Filter方法已经是一大漏洞漏泄的抽象。为什么过滤器输入表达式?为什么它不只是一个“正常”的代表?我想到的唯一答案就是这是因为表达式需要将谓词从其当前形式映射到其他不是面向对象的东西。

因此,尽管进行了英勇的努力,API仍然表明底层实现旨在成为关系型。换句话说,毕竟它并没有如此解耦。使用the IQueryable return type is also problematic for similar reasons

+2

Hello Mark,我相信您可能会直接对我的困境负责,我正在阅读您的书'依赖注入in。净'。在意识到自己实际上是Mary Rowan的时候,上面的内容是通过我的努力来弥补的:-)我试图做的是创建一种方法,让消费者在获取数据方面有更大的灵活性 - 我想我是试图避免必须在域服务上创建太多的检索方法(可能具有类似的签名)。感谢您的指导 - 我会再次考虑。 – Neilski 2012-02-08 21:36:00

2

这是一个有趣的问题。如果predicate是一个仿函数而不是表达式,那么翻译将很简单,但是您不会将表达式传递到生成的SQL中,而我收集的是您想要的(为了效率)。

如果Sql.Product和Domain.Product有一个共同的接口,你可以使用,但我从你不想去这样的问题收集。

我相信,无论是叶:1,“你不能这样做”,或者2.“你必须走表达式树和做翻译自己。” 2.对你来说可能会或可能不太实际。

+0

我在大部分的实现中使用了泛型,所以我并不想介绍一个类特定的接口,尽管我也许可以在基类之上使用继承来为实现添加一个类特定的接口。重新定义表达式树听起来很有趣,所以将尝试和研究,以查看它是否可能 - 感谢您的帮助 – Neilski 2012-02-08 18:47:21