实现 IQueryable时延迟执行的细粒度控制

发布于 2024-12-02 04:05:19 字数 1157 浏览 2 评论 0原文

我正在实现 IQueryable,到目前为止仅实现了“Where”调用的表达式访问者,其他所有内容当前均不受支持。该表达式被翻译为本机 T-SQL。当然,我计划随着时间的推移添加对其他方法调用的支持。

protected override Expression VisitMethodCall(MethodCallExpression m)
    {

        if (m.Method.DeclaringType == typeof(Queryable) && m.Method.Name == "Where")
        {

            sb.Append("SELECT * FROM (");

            this.Visit(m.Arguments[0]);

            sb.Append(") AS T WHERE ");

            LambdaExpression lambda = (LambdaExpression)StripQuotes(m.Arguments[1]);

            this.Visit(lambda.Body);

            return m;

        }

        throw new NotSupportedException(string.Format("Method '{0}' is not supported", m.Method.Name));

    }

由于我的“Where”支持使用延迟执行 - 我的问题是添加对其他方法的支持是否可能和/或良好的做法,例如“Select”,在后台延迟执行不 使用过,但对于使用 IQueryable 的任何人来说它都是透明的。因此,在延迟解决方案可用之前,会有一个可行的实施方案。

例如:

var _query = dbContext.Products
  .Where(x => x.ProductName == "") // deferred execution
  .Select(x => new { ... });       // cast ToList() under the hood and proceed

所以我想我的问题有两个方面,

1)是否可能/实施起来有多容易?

2)这是个好主意吗?

谢谢。

I am implementing IQueryable, and so far have only implemented an expression visitor for 'Where' calls and everything else is currently unsupported. The expression is translated into native T-SQL. I plan on adding support for additional method calls over time, of course.

protected override Expression VisitMethodCall(MethodCallExpression m)
    {

        if (m.Method.DeclaringType == typeof(Queryable) && m.Method.Name == "Where")
        {

            sb.Append("SELECT * FROM (");

            this.Visit(m.Arguments[0]);

            sb.Append(") AS T WHERE ");

            LambdaExpression lambda = (LambdaExpression)StripQuotes(m.Arguments[1]);

            this.Visit(lambda.Body);

            return m;

        }

        throw new NotSupportedException(string.Format("Method '{0}' is not supported", m.Method.Name));

    }

Being that my 'Where' support uses deferred execution -- my question is whether it is possible and/or good practice to add support for other methods, such as 'Select', where under the hood deferred execution is not used, but its transparent to whomever is using the IQueryable. So there is a working implementation until a deferred solution is available.

For instance:

var _query = dbContext.Products
  .Where(x => x.ProductName == "") // deferred execution
  .Select(x => new { ... });       // cast ToList() under the hood and proceed

So I guess my question is two-fold,

1) Is it possible / how easy is it to implement?

2) Is it even a good idea?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

多彩岁月 2024-12-09 04:05:19

当 Linq-To-Sql 中的某些内容无法转换为 SQL 时,它会引发异常。然后,程序员必须考虑这一点,并修改方法链以在调用此类方法之前首先包含对 .AsEnumerable 的调用。 IMO,这比在程序员不知情的情况下隐式执行此操作(通过在后台调用 .ToList)更清楚。

When something in Linq-To-Sql is not translatable to SQL it throws an exception. The programmer then has to consider that, and modify the method chain to include a call to .AsEnumerable first before calling such methods. IMO, that is more clear than doing so implicitly without the programmer knowing (by calling .ToList under the hood).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文