如何使用 LINQ return 在 C# 中选择所有属性或部分属性?
How to return either all properties or a selection of it in C# using LINQ?
我有一个接受 lambda 表达式的方法,该表达式指定 select 来自 table 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");
我从智能感知得到的错误是这样的:
Cannot implicitly convert type
'System.Collections.Generic.List' to
'System.Collections.Generic.List'
首先,我不理解这个令人困惑的错误消息,但我并不太在意。也就是说,我认为我需要的是一种将 MyTable
的整个对象转换为匿名类型然后 return 它的列表的方法,并通过 whole object 我的意思是匿名类型对象将包含 MyTable
的所有属性。我怎样才能做到这一点?
或者,如果有任何其他更好的方法来完成我想要的,请建议。
我认为你可以这样做:
if (columnsToSelect != null)
{
var result = query.Select(s => s.GetType().GetProperty("columnName").GetValue(s, null).ToString())
.Select(s => new MyTable()
{
YourProperty = s.ToString()
}).ToList();
}
allowing me to call this method in any of the following two ways:
...
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);
}
如果你能为你的table
定义一个接口
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] });
演示 table 在哪里
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 };
}
}
我有一个接受 lambda 表达式的方法,该表达式指定 select 来自 table 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");
我从智能感知得到的错误是这样的:
Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.List'
首先,我不理解这个令人困惑的错误消息,但我并不太在意。也就是说,我认为我需要的是一种将 MyTable
的整个对象转换为匿名类型然后 return 它的列表的方法,并通过 whole object 我的意思是匿名类型对象将包含 MyTable
的所有属性。我怎样才能做到这一点?
或者,如果有任何其他更好的方法来完成我想要的,请建议。
我认为你可以这样做:
if (columnsToSelect != null)
{
var result = query.Select(s => s.GetType().GetProperty("columnName").GetValue(s, null).ToString())
.Select(s => new MyTable()
{
YourProperty = s.ToString()
}).ToList();
}
allowing me to call this method in any of the following two ways:
...
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);
}
如果你能为你的table
定义一个接口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] });
演示 table 在哪里
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 };
}
}