1

我正在实现 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)这甚至是个好主意吗?

谢谢。

4

1 回答 1

1

当 Linq-To-Sql 中的某些内容无法转换为 SQL 时,它会引发异常。然后程序员必须考虑这一点,并修改方法链以.AsEnumerable在调用此类方法之前包含对 first 的调用。IMO,这比在程序员不知道的情况下隐式执行(通过在后台调用)更清楚.ToList

于 2011-08-30T00:11:58.057 回答