假设我有一个像:
这样的实体public class Car
{
public string Make { get; set; }
public string Model { get; set; }
public DateTime ReleaseDate { get; set; }
public int NumCreated { get; set; }
}
我们正在为我们的网站使用一个简单的MVP架构,其中包含一个视图层(ASP.NET网站,Presenter Layer(C#类库),逻辑层(C#类库),数据层(C#类库)。
假设我有一个显示带有可排序列标题的汽车列表的视图。我过去一直在做的是在逻辑层中进行所有排序,并且视图传递枚举,无论实体列表需要排序的列是什么。
这很痛苦,因为我需要为我拥有的每个实体维护一个枚举,并为该实体中的每个属性保留该枚举中的一个条目。
因此,例如,我们会做类似的事情:
CarLogic.cs
public IEnumerable<Car> GetCarsByYear(string year, SortColumn sortColumn, SortOrder sortOrder)
{
List<Car> cars = _carRepository.GetCarsByYear(year);
switch (sortColumn)
{
case SortColumn.Make:
cars.Sort((car1, car2) =>
sortOrder == SortOrder.Ascending
? car1.Make.CompareTo(car2.Make) :
car2.Make.CompareTo(car1.Make);
break;
case SortColumn.Model:
cars.Sort((car1, car2) =>
sortOrder == SortOrder.Ascending
? car1.Model.CompareTo(car2.Model) :
car2.Model.CompareTo(car1.Model);
break;
case SortColumn.ReleaseDate:
cars.Sort((car1, car2) =>
sortOrder == SortOrder.Ascending
? car1.ReleaseDate.CompareTo(car2.ReleaseDate) :
car2.ReleaseDate.CompareTo(car1.ReleaseDate);
break;
case SortColumn.NumCreated:
cars.Sort((car1, car2) =>
sortOrder == SortOrder.Ascending
? car1.NumCreated.CompareTo(car2.NumCreated) :
car2.NumCreated.CompareTo(car1.NumCreated);
break;
// ...
}
return cars;
}
这就是我一直这样做的。但是,这是一个非常手动的过程,如果一个实体有很多属性,那就很烦人了。
处理此问题的更好方法是什么?是否可以允许我的实体集合在属性上进行排序,而不必像这样手动执行所有属性?
答案 0 :(得分:12)
处理它的更好方法是:
public IEnumerable<Car> GetCarsByYear<T>(string year, SortOrder sortOrder,
Func<Car, T> fieldSelector) where T : IComparable<T>
{
List<Car> cars = _carRepository.GetCarsByYear(year);
cars.Sort((car1, car2) =>
sortOrder == sortOrder.Ascending
? fieldSelector(car1).CompareTo(fieldSelector(car2)) :
fieldSelector(car2).CompareTo(fieldSelector(car1)));
return cars;
}
GetCarsByYear(2010, SortOrder.Ascending, c => c.Model);
GetCarsByYear(2008, SortOrder.Descending, c => c.Make);
正如上面提到的海报,使用OrderBy
而不是将其存放在列表中也更为自然。
答案 1 :(得分:0)
您可以使用LINQ to Objects对您的实体执行排序
var sortedCars = cars.OrderBy(c => c.Model).ThenBy(c => c.Make);
或者您也可以使用OrderByDescending
和ThenByDescending
进行排序。
答案 2 :(得分:0)
使用IComparer类对集合进行排序会更简单吗?
答案 3 :(得分:0)
我能想到的最好的方法是使用方法
static List<T> SortList<T>(List<T> list, string column)
{
foreach (PropertyInfo p in typeof(T).GetProperties())
{
if (p.Name == column)
{
return list.OrderBy(c => c.GetType().GetProperty(p.Name).GetValue(c, null)).ToList();
}
}
return list;
}
然后可以使用
调用它var sortedList = SortList<Car>(cars, "NumCreated");
由于它使用反射,它将适用于任何不必更改的对象的列表。