使用变量值作为LINQ字段

我有这个对象:

public class MyObject { public int Id { get; set; } public string FieldA { get; set; } public string FieldB { get; set; } public string FieldC { get; set; } public string FieldD { get; set; } } 

我有一个这个对象的IList :

 IList MyListObject = new List(); 

我对它进行了Linq查询:

 var result = (from p in MyListObject where p.FieldC == "Test" select p.FieldA); 

在这种情况下,我返回“p.FieldA”但有时我需要返回“p.FieldB”。 我想把字段的名称(FieldA或FieldB)放在这样的变量中

 var myvar = "FieldB" var result = (from p in MyListObject where p.FieldC == "Test" select p.????); 

如何在Linq查询中使用myvar内容(FieldB)作为字段名称?

谢谢,

如果您的方法本身知道它必须在FieldA和FieldB之间进行选择,您可以使用:

 var whatField = "FieldA"; var result = (from p in MyListObject where p.FieldA == "Test" select (whatField == FieldA ? p.FieldA : p.FieldB)); 

如果你有两个选项,我会选择传递一个lambda;

 Func fieldGetter; // Option A, switch switch (whatField) { case "FieldA": fieldGetter = o => o.FieldA; break; case "FieldB": fieldGetter = o => o.FieldB; break; // More options } // Option B using reflection: var t = typeof(MyObject); var prop = t.GetProperty(whatField); fieldGetter = o => prop.GetValue(o, null); // Linq then looks like var result = (from p in MyListObject where p.FieldA == "Test" select fieldGetter(p)); 

使用lambda的优点是,你可以分割你的逻辑,什么字段以及如何查询。 你甚至可以让它适用于不同的类型:

 IEnumerable Query(IQueryable MyListObject, Func fieldGetter) { return result = (from p in MyListObject where p.FieldA == "Test" select fieldGetter(p)); } // call using: var result = Query(MyListObject, o => o.FieldA); 

FieldA和FieldB是同一类型吗?

如果是,那么你可以这样做:

 var result = (from p in MyListObject where p.FieldA == "Test" select (condition ? p.FieldA : p.FieldB)); 

如果您希望它与IQueryable一起使用,您可以执行以下操作:

 var filtered = MyListObject.Where(p => p.FieldA == "Test"); var results = condition ? filtered.Select(p => p.FieldA) : filtered.Select(p => p.FieldB); 

可以重构为:

 Expression> selector; switch(condition) { case "FieldA": selector = o => o.FieldA; break; case "FieldB": selector = o => o.FieldB; break; // other cases here default: throw new NotImplmentedException(); } var results = MyListObject.Where(p => p.FieldA == "Test").Select(selector); 

您可以使用reflection根据其名称获取属性的值。 这将允许您从您的class级中选择任何属性。

这是在MyObject类上使用扩展方法的示例:

  public static string GetPropertyValue(this MyObject myObj, string propertyName) { var propInfo = typeof(MyObject).GetProperty(propertyName); if (propInfo != null) { return propInfo.GetValue(myObj, null).ToString(); } else { return string.Empty; } } 

您的LINQ查询将如下所示:

 string propName = "FieldB"; var result = from m in myList where m.FieldC == "Test" select m.GetPropertyValue(propName);