我正在创建一个模拟数据源,我希望能够在SortExpressions列表中传递。
public SortExpression(string name, SortDirection direction)
{
this.name = name;
this.direction = direction;
}
使用Jon Skeet的代码以及整个班级更新。 GetData()只是用x个记录填充对象。
public class Data
{
public int Id { get; set; }
public Guid gId { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
public DateTime Created { get; set; }
public string SortMe { get; set; }
public static List<Data> GetFakeData(int start, int numberToFetch, IList<SortExpression> sortExpressions, IList<FilterExpression> filterExpressions, out int totalRecords)
{
DataCollection items = GetData();
IEnumerable<Data> query = from item in items select item;
bool sortExpressionsExist = sortExpressions != null;
if (sortExpressionsExist)
{
// Won't be read in the first iteration; will be written to
IOrderedEnumerable<Data> orderedQuery = null;
for (int i = 0; i < sortExpressions.Count; i++)
{
// Avoid single variable being captured: capture one per iteration.
// Evil bug which would be really hard to find :)
int copyOfI = i;
// Tailor "object" depending on what GetProperty returns.
Func<Data, object> expression = item =>
item.GetType().GetProperty(sortExpressions[copyOfI].Name);
if (sortExpressions[i].Direction == SortDirection.Ascending)
{
orderedQuery = (i == 0) ? query.OrderBy(expression)
: orderedQuery.ThenBy(expression);
}
else
{
orderedQuery = (i == 0) ? query.OrderByDescending(expression)
: orderedQuery.ThenByDescending(expression);
}
}
query = orderedQuery;
}
bool filterExpressionsExist = filterExpressions != null;
if (filterExpressionsExist)
{
foreach (var filterExpression in filterExpressions)
{
query.Where(item => item.GetType().GetProperty(filterExpression.ColumnName).GetValue(item, null).ToString().Contains(filterExpression.Text));
}
}
totalRecords = query.Count();
return query.Skip(start).Take(numberToFetch).ToList<Data>();
}
}
似乎没有做任何事情。编译,没有错误,只是没有排序。有什么想法吗?
答案 0 :(得分:27)
有两个问题。第一个是其他人提到的 - 你需要使用OrderBy
等返回的值。第二个是每次调用OrderBy
时,都会添加一个新的“主要”排序。在第一次订购之后,你真的想要ThenBy
。不幸的是,这让它非常丑陋。重构后仍然非常丑陋,但太不好......
IEnumerable<Data> query = from item in items select item;
if (sortExpressionsExist)
{
// Won't be read in the first iteration; will be written to
IOrderedEnumerable<Data> orderedQuery = null;
for (int i = 0; i < sortExpressions.Count; i++)
{
// Avoid single variable being captured: capture one per iteration.
// Evil bug which would be really hard to find :)
int copyOfI = i;
// Tailor "object" depending on what GetProperty returns.
Func<Data, object> expression = item =>
item.GetType()
.GetProperty(sortExpressions[copyOfI].Name)
.GetValue(item, null);
if (sortExpressions[i].Direction == SortDirection.Ascending)
{
orderedQuery = (i == 0) ? query.OrderBy(expression)
: orderedQuery.ThenBy(expression);
}
else
{
orderedQuery = (i == 0) ? query.OrderByDescending(expression)
: orderedQuery.ThenByDescending(expression);
}
}
query = orderedQuery;
}
答案 1 :(得分:5)
OrderBy返回一个新的IEnumerable,所以你需要做类似的事情:
IEnumerable<Data> results
= query.OrderBy(item => item.GetType().GetProperty(sortExpressions[i].Name));
答案 2 :(得分:2)
OrderBy / OrderByDescending'运算符'就像String.ToUpper()一样工作,即他们接受你调用它的东西,并产生一个具有你要求的“副本”。
换句话说,而不是说:
query.Orderby(item->item.X)
你应该做
query = query.Orderby(item->item.X)
或
sortedResult = query.Orderby(item->item.X)
[正如Jon Skeet指出的那样,在答案中使用ThenBy
/ ThenByDescending
]
答案 3 :(得分:2)
查询不可变,因此OrderBy返回一个新对象。您需要拨打同一个电话,但在开头添加“query =”。
query = query.OrderBy(item => item.GetType().GetProperty(sortExpressions[i].Name));
答案 4 :(得分:2)
OrderBy on IEnumerable返回一个IOrderedEnumerable。它没有对它们进行排序。所以从.OrderBy获得返回值,你会没事的。
答案 5 :(得分:1)
这将有效:
YourCollection.Orderby(item => item.Property1).ThenBy(item => item.Property2);