Детальное управление отложенным выполнением при реализации IQueryable <T> - PullRequest
1 голос
/ 30 августа 2011

Я реализую IQueryable, и до сих пор реализовал только посетитель выражений для вызовов «Где», а все остальное в настоящее время не поддерживается. Выражение переведено на родной 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));

    }

Поскольку моя поддержка «Где» использует отложенное выполнение, мой вопрос заключается в том, возможно ли и / или целесообразно добавить поддержку для других методов, таких как «Выбор», где под капотом отложенное выполнение равно не используется , но он прозрачен для всех, кто использует IQueryable. Таким образом, существует рабочая реализация, пока не будет доступно отложенное решение.

Например:

var _query = dbContext.Products
  .Where(x => x.ProductName == "") // deferred execution
  .Select(x => new { ... });       // cast ToList() under the hood and proceed

Так что я думаю, мой вопрос двоякий,

1) Возможно ли / насколько легко это реализовать?

2) Это даже хорошая идея?

Спасибо.

1 Ответ

1 голос
/ 30 августа 2011

Когда что-то в Linq-To-Sql не переводится в SQL, возникает исключение. Затем программист должен учесть это и изменить цепочку методов, включив в нее вызов .AsEnumerable, прежде чем вызывать такие методы. ИМО, это более понятно, чем делать это неявно, без ведома программиста (вызывая .ToList под капотом).

...