我有这个对象:
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<MyObject> MyListObject = new List<MyObject>();
我对它进行了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)作为字段名称?
谢谢,
答案 0 :(得分:5)
如果您的方法本身知道它必须在FieldA和FieldB之间进行选择,您可以使用:
var whatField = "FieldA";
var result = (from p in MyListObject
where p.FieldA == "Test"
select (whatField == FieldA ? p.FieldA : p.FieldB));
如果您有更多2个选项,我会选择传递lambda;
Func<MyObject, object> 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<T> Query<T>(IQueryable<MyObject> MyListObject, Func<MyObject, T> fieldGetter) {
return result = (from p in MyListObject
where p.FieldA == "Test"
select fieldGetter(p));
}
// call using:
var result = Query(MyListObject, o => o.FieldA);
答案 1 :(得分:0)
FieldS和FieldS是同一类型吗?
如果是,那么你可以这样做:
var result = (from p in MyListObject where p.FieldA == "Test"
select (condition ? p.FieldA : p.FieldB));
答案 2 :(得分:0)
您可以使用反射根据其名称获取属性的值。这将允许您从您的班级中选择任何属性。
以下是在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);
答案 3 :(得分:0)
如果您希望它与IQueryable一起使用,您可以执行以下操作:
var filtered = MyListObject.Where(p => p.FieldA == "Test");
var results = condition ? filtered.Select(p => p.FieldA) : filtered.Select(p => p.FieldB);
可以重构为:
Expression<Func<MyObject,string>> 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);