Ibraheem
Ibraheem

Reputation: 2358

Extending LINQ Expressions

Newbie LINQ Expressions question-

Expression<Func<TLookupModel, TValue>> idSelector;
IEnumerable<TLookupModel> source;
TValue id;

I'm trying to do (pseudo-code):

source.AsQueryable().FirstOrDefault(x => idSelector == id)

My feeble attempt thus far is along the lines of:

var expressionParam = idSelector.Parameters.First();

ConstantExpression selectedValueConstant = Expression.Constant(id, typeof(TValue));

var idEqualExpression = Expression.Equal(idSelector, selectedValueConstant);

var lambda = Expression.Lambda<Func<TLookupModel, bool>>(idEqualExpression, expressionParam);

var selectedSourceItem = source.AsQueryable().FirstOrDefault(lambda);

I think that gives you a guess as to how I've been thinking so far. I've tried with and without the parameters, different combinations of Expression method calls, trying to get the "parameter" to come from the FirstOrDefault() call, but after reading lots of tutorials I can't get my head around how to extend a "member" expression to equal a constant in this way.

Upvotes: 2

Views: 311

Answers (1)

Ortiga
Ortiga

Reputation: 8814

You got really close.

Your idExpression is an Expression in the form of x => x.Property. However, you're passing the whole expression to the Equal expression. Change that to pass only the body:

var idEqualExpression = Expression.Equal(idSelector.Body, selectedValueConstant);

Then you can compile the lambda and pass it to FirstOrDefault without casting to a queryable:

var selectedSourceItem = source.FirstOrDefault(lambda.Compile());

Upvotes: 2

Related Questions