Question

I would like to replace the lambda expression in the following code

var idQuery = Query<ApiStatisticsAggregatedStats>.EQ(t => t.Api, id);

with a func. Hovering over the statement it says the declaration is

Func<ApiStatisticsAggregatedStats, string>

The following code gives an error though,

Func<ApiStatisticsAggregatedStats, string> idFunc = x => x.Api
var idQuery = Query<ApiStatisticsAggregatedStats>.EQ(idFunc, id);

Error:

The best overloaded method match for Query<ApiStatisticsAggregatedStats>.EQ<string>(Expression<Func<ApiStatisticsAggregatedStats, IEnumerable<string>>>, string) has some invalid arguments.

Where did that IEnumerable come from? What am I doing wrong?

Was it helpful?

Solution

Query providers, like mongoDB query provider, use expression trees instead of delegates. That's why you have to declare your variable as

Expression<Func<ApiStatisticsAggregatedStats, string>> idFunc = x => x.Api

You can still assign a lambda expression to Expression<Func<...>> variable, because compiler can transform your lambda into proper method calls from Expression class during compilation.

When a lambda expression is assigned to a variable of type Expression<TDelegate>, the compiler emits code to build an expression tree that represents the lambda expression.

However, it works for single-line lambdas only.

The C# and Visual Basic compilers can generate expression trees only from expression lambdas (or single-line lambdas). It cannot parse statement lambdas (or multi-line lambdas).

If you'd try doing following:

Expression<Func<ApiStatisticsAggregatedStats, string>> idFunc = x => { return x.Api };

(notice { and }) you'd get compile error saying compiler is not able to transform multi-line lambda into expression tree.

Bot quotes come from Expression Trees (C# and Visual Basic).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top