【问题标题】:Convert base class of a Linq Expression转换 Linq 表达式的基类
【发布时间】:2012-02-08 17:19:48
【问题描述】:

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

例如:

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

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

【问题讨论】:

    标签: linq-to-sql dependency-injection


    【解决方案1】:

    即使你想做的事情是可能的,真正的问题应该是:这样做会有所收获吗?

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

    因此,尽管付出了巨大的努力,API 仍然表明底层实现是关系型的。换句话说,它毕竟没有那么解耦。

    另外,the IQueryable return type is also problematic for similar reasons的使用。

    【讨论】:

    • 你好马克,我相信你可能直接导致我的困境,我目前正在阅读你的书“.NET中的依赖注入”。在意识到我实际上是 Mary Rowan 之后,以上是通过我的努力来弥补的 :-) 我试图做的是创建一种方法,让消费者在检索数据时具有更大的灵活性——我想我是试图避免在域服务上创建过多的检索方法(可能具有相似的签名)。感谢您的指导 - 我会再考虑一下。
    【解决方案2】:

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

    如果 Sql.Product 和 Domain.Product 有一个通用接口,您可以使用它,但我从问题中得知您不想那样做。

    我相信要么:1.“你做不到”,要么2.“你必须遍历表达式树并自己进行翻译。” 2. 可能对你实用,也可能不实用。

    【讨论】:

    • 我在大部分实现中都使用泛型,所以我真的不想引入一个特定于类的接口,尽管我也许可以在基类之上使用继承来添加一个特定于类实现的接口。重新定义表达式树听起来很有趣,因此将尝试研究它是否有可能 - 感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 2022-01-01
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多