实现 IQueryable时延迟执行的细粒度控制
我正在实现 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当 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).