因為專案中用到linq to mongo,所以我看了一下MongoQueryProvider 的實作.
但我不懂這段程式碼的意思
public object Execute(Expression expression)
{
var plan = BuildExecutionPlan(expression);
var lambda = expression as LambdaExpression;
if (lambda != null)
{
var fn = Expression.Lambda(lambda.Type, plan, lambda.Parameters);
return fn.Compile();
}
else
{
var efn = Expression.Lambda<Func<object>>(Expression.Convert(plan, typeof(object)));
var fn = efn.Compile();
return fn();
}
}
在什麼情況下expression會是LambdaExpression類型呢?
因為IQueryable的擴充方法,呼叫的是Expression.Call()來產生的表達式樹,
用linq表達式產生的表達式樹都會是 MethodCallExpression型
就像下面這樣
public static IQueryable<TResult> Select<TSource,TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector) {
if (source == null)
throw Error.ArgumentNull("source");
if (selector == null)
throw Error.ArgumentNull("selector");
return source.Provider.CreateQuery<TResult>(
Expression.Call(
null,
((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TResult)),
new Expression[] { source.Expression, Expression.Quote(selector) }
));
}