Question

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.

Was it helpful?

Solution

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top