我有两个模型:
public class CarRent
{
public string CarName { get; set; }
public string SystemId { get; set; }
public DateTime RentEndDate { get; set; }
}
public class CarPurchase
{
public string CarName { get; set; }
public string SystemId { get; set; }
public decimal Mileage { get; set; }
}
我需要将它们组合到一个列表中,按CarName分组,然后在每个组中首先需要按SystemId排序模型,但是如果模型具有相同的SystemId-我需要按RentEndDate排序CarRent模型,按Mileage排序CarPurchase.
我尝试过的
我定义了一个接口:
public interface ICarPurchaseOrdered
{
string CarName { get; }
string SystemId { get; }
string Order { get; }
}
并让我的模型来实现它,Order属性仅返回二阶条件的字符串表示形式,然后定义了一个视图模型:
public class GroupedCardList
{
public string CarName { get; set; }
public IEnumerable<ICarPurchaseOrdered> Cars { get; set; }
}
然后我有一个将我的模型分组的石斑鱼:
public class CarGrouper
{
IEnumerable<GroupedCardList> Group(IEnumerable<ICarPurchaseOrdered> cars)
{
return cars.GroupBy(c => c.CarName)
.OrderBy(c => c.Key)
.Select(c => new GroupedCardList()
{
CarName = c.Key,
Cars = c.OrderBy(n => n.SystemId)
.ThenBy(n => n.Order)
});
}
}
但这行不通,因为它会对字符串进行排序,而我在购买Milage = 90的汽车之前先购买Milage = 1200的汽车.
我知道这个例子有些人为,但这完全代表了我现在遇到的问题.请给我一些建议.
解决方法:
一种方法是实现自定义IComparer.如果提取公共基类:
public class Car
{
public string CarName { get; set; }
public string SystemId { get; set; }
}
public class CarRent : Car
{
public DateTime RentEndDate { get; set; }
}
public class CarPurchase : Car
{
public decimal Mileage { get; set; }
}
然后,将IComparer< Car>实现可能如下所示:
public class CarComparer : IComparer<Car>
{
public int Compare(Car x, Car y)
{
// compare by system id first
var order = string.Compare(x.SystemId, y.SystemId);
if (order != 0)
return order;
// try to cast both items as CarRent
var xRent = x as CarRent;
var yRent = y as CarRent;
if (xRent != null && yRent != null)
return DateTime.Compare(xRent.RentEndDate, yRent.RentEndDate);
// try to cast both items as CarPurchase
var xPurc = x as CarPurchase;
var yPurc = y as CarPurchase;
if (xPurc != null && yPurc != null)
return decimal.Compare(xPurc.Mileage, yPurc.Mileage);
// now, this is awkward
return 0;
}
}
然后,您可以将比较器实例传递给List.Sort
和Enumerable.OrderBy
.