简体   繁体   English

实现IQueryable时对延迟执行的细粒度控制<T>

[英]Fine-grained control of deferred execution when implementing IQueryable<T>

I am implementing IQueryable, and so far have only implemented an expression visitor for 'Where' calls and everything else is currently unsupported. 我正在实现IQueryable,到目前为止,仅实现了“ Where”调用的表达式访问者,而当前不支持其他所有访问。 The expression is translated into native T-SQL. 将该表达式转换为本地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. 因为我的“在哪里”支持使用了延迟执行-我的问题是是否有可能和/或好的做法来增加对其他方法(例如“选择”)的支持,在这种情况下, 使用延迟执行,但是透明给使用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? 1)是否可能/实施起来有多容易?

2) Is it even a good idea? 2)这是个好主意吗?

Thanks. 谢谢。

When something in Linq-To-Sql is not translatable to SQL it throws an exception. 当Linq-To-Sql中的某些内容不可翻译为SQL时,它将引发异常。 The programmer then has to consider that, and modify the method chain to include a call to .AsEnumerable first before calling such methods. 然后,程序员必须考虑到这一点,并在调用此类方法之前修改方法链以包括对.AsEnumerable调用。 IMO, that is more clear than doing so implicitly without the programmer knowing (by calling .ToList under the hood). IMO,这比在程序员不知道的情况下(通过在.ToList调用.ToList )隐式执行操作更清楚。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM