문제

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.

도움이 되었습니까?

해결책

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top