How to turn a string into a linq expression?

Similarly: Convert string to Linq.Expressions or use string as a selector?

Similar to one: Passing a Linq expression as a string?

Another question with the same answer: How to create a dynamic Linq expression based on lambda from a string in C #?

Reason for asking for something that has so many similar questions:

The accepted answer in such questions is unacceptable, since they all refer to the library from 4 years ago (provided that it was written by code wizard Scott Gu), written for the old structure (.net 3.5) and does not provide anything but a link as an answer .

There is a way in the code to do this without including the whole library.

Here is a sample code for this situation:

public static void getDynamic<T>(int startingId) where T : class { string classType = typeof(T).ToString(); string classTypeId = classType + "Id"; using (var repo = new Repository<T>()) { Build<T>( repo.getList(), b => b.classTypeId //doesn't compile, this is the heart of the issue //How can a string be used in this fashion to access a property in b? ) } } public void Build<T>( List<T> items, Func<T, int> value) where T : class { var Values = new List<Item>(); Values = items.Select(f => new Item() { Id = value(f) }).ToList(); } public class Item { public int Id { get; set; } } 

Note that this does not look to turn an entire string into an expression such as

 query = "x => x.id == somevalue"; 

But instead, it tries to use only the string as access

 query = x => x.STRING; 
+8
generics c # linq asp.net-mvc-3
source share
3 answers

An expression tree is created here. I still don't know if this will work with the Entity infrastructure, but I find it worth a try.

 Func<T, int> MakeGetter<T>(string propertyName) { ParameterExpression input = Expression.Parameter(typeof(T)); var expr = Expression.Property(input, typeof(T).GetProperty(propertyName)); return Expression.Lambda<Func<T, int>>(expr, input).Compile(); } 

Name it as follows:

 Build<T>(repo.getList(), MakeGetter<T>(classTypeId)) 

If you can use Expression<Func<T,int>> instead of just Func , just delete the Compile call (and change the MakeGetter signature).


Edit : In the comments, TravisJ asked how he can use it as follows: w => "text" + w.classTypeId

There are several ways to do this, but for readability, I would recommend introducing a local variable first, for example:

 var getId = MakeGetter<T>(classTypeId); return w => "text" + getId(w); 

The main thing is that a getter is just a function, and you can use it exactly as you would normally. Read Func<T,int> as follows: int DoSomething(T instance)

+15
source share

Here is the extension method for my testing code (linqPad):

 class test { public string sam { get; set; } public string notsam {get; set; } } void Main() { var z = new test { sam = "sam", notsam = "alex" }; z.Dump(); z.GetPropertyByString("notsam").Dump(); z.SetPropertyByString("sam","john"); z.Dump(); } static class Nice { public static void SetPropertyByString(this object x, string p,object value) { x.GetType().GetProperty(p).SetValue(x,value,null); } public static object GetPropertyByString(this object x,string p) { return x.GetType().GetProperty(p).GetValue(x,null); } } 

results:

results

+2
source share

I have not tried this and am not sure if this will work, but you could use something like:

b => b.GetType().GetProperty(classTypeId).GetValue(b, null);

+1
source share

All Articles