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. 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 IQuery开发者_运维技巧able. 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.
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).
精彩评论