我正在实现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)这是一个好主意吗?
感谢。
答案 0 :(得分:1)
当Linq-To-Sql中的某些内容无法转换为SQL时,它会抛出异常。然后,程序员必须考虑这一点,并在调用此类方法之前修改方法链以包含对.AsEnumerable
的调用。 IMO,如果没有程序员知道(通过在引擎盖下调用.ToList
),这比隐含地更明确。