How to create dynamic lambda based Linq expression from a string in C#?
Asked Answered
C

1

2

I'm having some difficulty creating Lambda-based Linq expressions from a string. Here is my basic case using this sample object/class:

public class MockClass
{
    public string CreateBy { get; set; }
}

Basically I need to convert a string like this:

string stringToConvert = “x => x.CreateBy.Equals(filter.Value, StringComparison.OrdinalIgnoreCase”;

Into a to predicate/linq expression:

System.Linq.Expressions.Expression<Func<T, bool>>  or in this example 
System.Linq.Expressions.Expression<Func<MockClass, bool>>

So it is equivalent to the Linq expression inside of the Where method below:

query = query.Where(x => x.CreateBy.Equals(filter.Value,
StringComparison.OrdinalIgnoreCase));

I've tried using the following helpers but can't seem to figure out how to get them to work in this type of case where I want to be able to build a linq expression from string that is not know ahead of time: http://www.albahari.com/nutshell/predicatebuilder.aspx

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx (it’s now available as a NuGet package as well called “DynamicQuery”)

Cargo answered 11/4, 2012 at 22:24 Comment(2)
Why are you putting the expression in a string in the first place? Is the user inputting that expression? Save it in its proper type.Anderegg
The non-developer user is dynamically entering a query syntax that is similar to a search syntax that gets passed in the querystring, then that needs to eventually do all of this, e.g. it's a little more difficult to get the proper type when it can be any property or sub-property of a vast number of types and nested types.Cargo
A
1

A similar question was asked here:

Is there an easy way to parse a (lambda expression) string into an Action delegate?

As I understand it, this 'Dynamic Query' is actually a framework for passing in restrictions for a Where clause without using a lambda expression.

The significance of that is that lambda expressions are not dynamic methods, they're anonymous methods. If you ever take a look in an assembly, you'll see that your lambda expressions are converted into closures with any free variables as fields. The class has a method with a signature matching yours, field variables are assigned at the point of invocation.

One good way to think about that is that it implies that your lambda expression is interpreted by the c# compiler at compile-time, and variables are resolved by instantiating an object from this class at run-time.

To demonstrate this, consider the following:

var myLambda = x => x * x

You'll notice this doesn't work. That's because, in order to create the related class/method, the compiler must know, at compile-time, the type of x.

All of this is important because the notion of a lambda expression doesn't exist at the CLR at run-time (in the same form it is in code). A string that looks like a lambda expression is exactly that...

Adelinaadelind answered 11/4, 2012 at 23:32 Comment(1)
This works for top-level properties using the Dynamic Linq library, but I cannot get sub-properties or sub-collections to subsitute. var test = string.Format("{0} == {1}", propertyName, value); var e = DynamicExpression.ParseLambda<EF.Discount, bool>(test); I wish I could get something like this to translate: query = query.Where( x => x.MockClass.SubCollection.Any(y => y.Name.StartsWith(filter.Value)));Cargo

© 2022 - 2024 — McMap. All rights reserved.