In order to support queries like:
var e10 = from t in gd
where t is GDFileResult &&
t.Contains("sql")
select ((GDFileResult)t).Location;
foreach (string s in e10) {
Console.WriteLine("The file name is: " + s);
}
We need to add support for handling the
Select
method. The query described above is processed by the compiler as:
gd.Where( ... ).Select( ... );
Given that the
Where
method processing returns an instance of GDQuery
, then the processing of the Select
method call is done in the GDQuery.CreateQuery
method. The implementation of this method is the following:
public IQueryable<T> CreateQuery<T>(System.Linq.Expressions.Expression expression)
{
if (IsSelectMethodCall(expression))
{
MethodCallExpression methodCallExpr = (MethodCallExpression)expression;
UnaryExpression unaryQuoteExpr =
(UnaryExpression)methodCallExpr.Arguments[1];
LambdaExpression lambdaExpr =
(LambdaExpression)unaryQuoteExpr.Operand;
GDQuery query =
(GDQuery)((ConstantExpression)methodCallExpr.Arguments[0]).Value;
return query.AsEnumerable<GDResult>().Select(
(Func<GDResult,T>)lambdaExpr.Compile()).AsQueryable<T>();
}
else
{
throw new NotSupportedException("Not supported method call");
}
}
What this method does is to delegate the execution to the
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector);
method , which is the extension method fro IEnumerable. The only thing we also need to do is to compile the lambda expression that represents the filter.This is done this way because elements in the projection section cannot be used to make the Google Desktop query more specific. This is not the case of Linq To SQL where the projection section affects the way the query is processed by the DBMS.
Now we can write queries like:
var e11 = from t in gd
where t is GDFileResult &&
t.Contains("sql")
select new { FileName = ((GDFileResult)t).Location,
Info = new FileInfo(((GDFileResult)t).Location)};
foreach (var fResult in e11)
{
Console.WriteLine(fResult.Info.Name);
}