使用变量值作为LINQ字段

Kri*_*s-I 1 c# 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; }
}
Run Code Online (Sandbox Code Playgroud)

我有一个这个对象的IList <>:

IList<MyObject> MyListObject = new List<MyObject>();
Run Code Online (Sandbox Code Playgroud)

我对它进行了Linq查询:

var result = (from p in MyListObject where p.FieldC == "Test" select p.FieldA);
Run Code Online (Sandbox Code Playgroud)

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

var myvar = "FieldB"
var result = (from p in MyListObject where p.FieldC == "Test" select p.????);
Run Code Online (Sandbox Code Playgroud)

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

谢谢,

GvS*_*GvS 5

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

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

如果你有两个选项,我会选择传递一个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));
Run Code Online (Sandbox Code Playgroud)

使用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);
Run Code Online (Sandbox Code Playgroud)