Passing Lambda as a method parameter: Some issues
I am building an IQueryable extension that can perform queries on nested object properties (that is the hope).
I would like to apply this extension to a class, then pass the desired nested object to the extension to further build a where clause
Here is an example of how I would call the extension:
_context.ClassA.CustomExtension(a => a.ClassB)
(ClassB is an object instance on Class A)
All examples online show some expression that returns a value, however in this case I don't have one. I just want the extension to know it should query this nested Class on _context.ClassA
. Not sure how to set up the parameter.
What is the correct way to go about this?7 Replies
If I understand you correctly, you want to pass in a Function that knows how to query your nested property, but you probably need a generic parameter to specify the expected outcome:
Hi. thanks for getting back to me. What I'm trying to do is create a dynamic extension query that can encapsulate the where statement in
_context.ClassA.Where(a => a.ClassB.someVal == someReferenceVal)
. I was working with Expressions trees, and the problem there is getting the nested object and its propery to build that where clause. Not sure how to go about it. Though I am open to other ideas if my initial idea is wrong. The key idea being what options exist to encapsulate the .Where(a => a.ClassB.someVal == someReferenceVal)
Ah, so you are really building the
IQueryable
! I got frustrated in my attempts years ago, but have a look at Joe Albahari's approach here: https://www.albahari.com/nutshell/linqkit.aspxok, thanks for the reference. I was trying to build something like this using expressions rather than sql syntax
private sealed class referenceValue<T>
{
public int Value {get; set;}
}
public static IQueryable<T> WithIdExtension<T>(this IQueryable<T> query) where T : class
{
//entity we are applying filter to
var memberEntity = Expression.Parameter(typeof(T))
//the property we want to access
var accessEntityProperty = Expression.PropertyOrField(memberEntity, "SpecificId')
var objectValue = new referenceValue<T> {Value = someInternalMethod.GetValue()}
//this will parameterize value when converted to sql
var value = Expression.PropertyOrField(Expression.Constant(objectValue, "Value");
var equalExpression = Expression.Equal(accessEntityParameter, value)
Expression<Func<T, bool>> whereLambda = Expression.Lambda<Func<T, bool>>(equalExpression, memberEntity)
return query.Where(whereLambda)
}
dunno if reflection could be used to search for the nested Object class once I got the type T is?I'm familiar enough with what you are doing to re-iterate that Albahari should be a gold-standard reference. But I gave up on this approach about ten years ago and went with explicit SQL and some extensions that wrapped simple Ado.Net operations with a fluent api. I won't be able to help you much with the Visitor pattern and expression tree builder needed here. 😕
ok. Thanks again for the reference, that is very helpful. I will take a deep dive into that.
I'm curious though. Is this going against an RDBMS table, or is it Linq-to-Entity, or is it against a document database? If ClassB is a nested property of ClassA, does your query presume a join clause?