使用反射在C#中创建动态LINQ语句

时间:2014-05-22 18:50:53

标签: c# linq reflection

如果我有像

这样的LINQ语句
x = Table.SingleOrDefault(o => o.id == 1).o.name;

如何更换" id"和"名称"用反射传入变量?我尝试时,我不断将对象引用设置为对象错误的实例。我的尝试是像

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

任何帮助都会很棒。感谢。

2 个答案:

答案 0 :(得分:24)

您应该使用表达式树而不是反射。它会表现得更好,并且您可以将它与LINQ to Objects和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);

然后,您可以使用反射获得Name属性(您只需执行一次,因此使用反射可以做到这一点。

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

Test类定义为

public class Test
{
    public int Id { get; set; }
    public string Name { get; set; }
}

答案 1 :(得分:1)

您无法使用反射,但您可以按照here所述使用动态Linq。如果您正在使用Entity Framework,那么您还应该能够使用Entity SQL,它基本上是一个硬编码的SQL字符串。