Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use reflection to make dynamic LINQ statements in C#

If I have a LINQ statement like

x = Table.SingleOrDefault(o => o.id == 1).o.name;

how can I replace "id" and "name" with passed in variables using reflection? I keep getting object reference not set to instance of an object errors when I try. My attempts are things like

x = (string)Table.SingleOrDefault(o => (int?)o.GetType().GetProperty(idString)
.GetValue(o, null) == 1).GetType().GetField(nameString).GetValue(x);

Any help would be great. Thanks.

like image 873
erosebe Avatar asked May 22 '14 18:05

erosebe


2 Answers

You should use Expression Trees instead of reflection. It will perform better, and you'll be able to use it with both LINQ to Objects and LINQ to SQL/Entities.

var source = new List<Test> { new Test { Id = 1, Name = "FirsT" }, new Test { Id = 2, Name = "Second" } };
var idName = "Id";
var idValue = 1;

var param = Expression.Parameter(typeof(Test));
var condition =
    Expression.Lambda<Func<Test, bool>>(
        Expression.Equal(
            Expression.Property(param, idName),
            Expression.Constant(idValue, typeof(int))
        ),
        param
    ).Compile(); // for LINQ to SQl/Entities skip Compile() call

var item = source.SingleOrDefault(condition);

then, you can get Name property using reflection (you'll do it just once, so it's fine to do it using reflection.

var nameName = "Name";
var name = item == null ? null : (string) typeof(Test).GetProperty(nameName).GetValue(item);

Test class is defined as

public class Test
{
    public int Id { get; set; }
    public string Name { get; set; }
}
like image 125
MarcinJuraszek Avatar answered Sep 30 '22 08:09

MarcinJuraszek


You can't use reflection, but you can use dynamic Linq as described here. If you are using Entity Framework for this, you should also be able to use Entity SQL, which is basically a hard-coded SQL string.

like image 38
Brian Mains Avatar answered Sep 30 '22 08:09

Brian Mains