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