如何使用LINQ在C#中返回所有属性或选择它?

时间:2017-03-05 07:19:28

标签: c# linq anonymous-types

我有一个方法接受一个lambda表达式,指定从表MyTable中选择哪些列。

public List<T> GetSelection<T>(string a, Expression<Func<MyTable, T>> columnsToSelect = null)
{
    IQueryable<MyTable> query = _myTableRepository.Where(c => c.Name == a);

    if (columnsToSelect != null)
        return query.Select(columnsToSelect).ToList();

    return query.ToList(); // Intellisense gives an error here, please read on
}

如您所见,columnsToSelect的默认值为null,允许我通过以下两种方式之一调用此方法:

// passing in a lambda expression to select the columns I want
var result = GetSelection("AValue", t => new { t.Prop1, t.Prop2 }); 

// or like this, in which case I want all the columns
var result = GetSelection("AValue");

我从intellisense得到的错误是:

  

无法隐式转换类型   'System.Collections.Generic.List'到   'System.Collections.Generic.List'

首先,我不明白这个令人困惑的错误信息,但我对此并不感到困扰。也就是说,我认为我需要的是一种将MyTable的整个对象转换为匿名类型然后返回它的列表的方法,并通过整个对象我的意思是匿名类型object将包含MyTable的所有属性。我怎样才能做到这一点?

或者,如果还有其他更好的方法可以实现我的目标,请提出建议。

3 个答案:

答案 0 :(得分:3)

  

允许我以下列两种方式之一调用此方法:

     

...

var result = GetSelection("AValue");

不,那是不允许的。编译器无法在此处推断出T的类型。唯一的方法是创建重载而不是使用默认值。在这一点上,问题变得微不足道:

public List<T> GetSelection<T>(
    string a, Expression<Func<MyTable, T>> columnsToSelect)
{
    return _myTableRepository.Where(c => c.Name == a).Select(columnsToSelect)
        .ToList();
}

public List<MyTable> GetSelection<MyTable>(string a)
{
    return GetSelection(a, t => t);
}

答案 1 :(得分:1)

我认为你可以这样做:

if (columnsToSelect != null)
{
    var result = query.Select(s => s.GetType().GetProperty("columnName").GetValue(s, null).ToString())
                      .Select(s => new MyTable()
                      {
                          YourProperty = s.ToString()
                      }).ToList();
}

答案 2 :(得分:1)

如果您可以为表格定义界面

public interface IMyTable<T>
{
    string Name { get; set; }
    T GetAll();
}

然后这将编译

public List<T> GetSelection<T>(string a, Expression<Func<IMyTable<T>, T>> columnsToSelect = null)
{
    IQueryable<IMyTable<T>> query  = (IQueryable<IMyTable<T>>) _myTableRepository.Where(c => c.Name == a);

    if (columnsToSelect == null)
        columnsToSelect = (Expression<Func<IMyTable<T>, T>>)(table => (table.GetAll()));

    return query.Select(columnsToSelect).ToList();

}

用法演示

IMyTable<List<object>> xxx = new MyTable() { Surname = "b", Addresss = 1 };
xxx.Name = "a";
IMyTable<List<object>> yyy = new MyTable() { Surname = "d", Addresss = 2 };
yyy.Name = "c";
var repo = new List<IMyTable<List<object>>>() { xxx, yyy }.AsQueryable();
var Test = new Test<List<object>>(repo);
var generic = Test.GetSelection<List<object>>("c");
var specific = Test.GetSelection<List<object>>("c",
                (Expression<Func<IMyTable<List<object>>, List<object>>>) 
                    (x => new List<object>() { x.Name, ((MyTable)x).Addresss }));
var specifc2Columns = specific
    .Select(rows => new { Name = rows[0], Address = rows[1] });

演示表是

 internal class MyTable : IMyTable<List<object>>
 {
     public string Surname { get; set; }
     public int Addresss { get; set; }
     string IMyTable<List<object>>.Name{ get; set; }
     List<object> IMyTable<List<object>>.GetAll()
     {
         return new List<object>() { ((IMyTable<List<object>>)this).Name, Surname, Addresss };
     }
 }