转换Linq表达式的基类

时间:2012-02-08 17:19:49

标签: linq-to-sql dependency-injection

我正在尝试构建一个解耦的域模型。我的(抽象)域模型定义了一个实体,例如'Product',然后我的具体SQL实现为该Domain实体提供了一种转换方法。

例如:

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 个答案:

答案 0 :(得分:2)

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

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

我相信会留下:1。“你不能这样做”或2.“你必须走表达树并自己做翻译。” 2.对你来说可能适用也可能不实用。

答案 1 :(得分:2)

即使您想要做的事情是可能的,真正的问题应该是:通过这样做可以获得什么?

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

因此,尽管做了英勇的努力,但API仍然背叛了底层实现旨在成为关系。换句话说,毕竟它并没有那么脱钩。

此外,使用the IQueryable return type is also problematic for similar reasons