使用Linq对多个表中的多个列表进行排序
本文关键字:列表 排序 Linq 使用 | 更新日期: 2023-09-27 18:26:34
目前,我的数据库中有多个表,它们的列略有不同,可以为一个项目定义不同的"历史"元素。
所以我有了我的项目表;
int ItemId {get;set}
string Name {get;set}
Location Loc {get;set}
int Quantity {get;set}
我可以对这些物品做一些事情,比如移动、增加数量、减少数量、预订给客户、"挑选"物品等等。所以我制作了多个"历史表",因为它们有不同的值来保存E.g
public class MoveHistory
{
public int MoveHistoryId { get; set; }
public DateTime Date { get; set; }
public Item Item { get; set; }
public virtual Location Location1Id { get; set; }
public virtual Location Location2Id { get; set; }
}
public class PickingHistory
{
public int PickingHistoryId { get; set; }
public DateTime Date { get; set; }
public Item Item { get; set; }
public int WorksOrderCode { get; set; }
}
这很好,除了我想显示列表中显示的项目的完整历史记录;
项目123于2013年2月23日从位置1移动到位置2
项目123于2013年2月24日从工作订单421 中提取
我使用的是Entity Framework、.NET 4.5、WPF和使用Linq进行查询,但无法找到一种方法来获取这些历史元素列表,并根据它们的日期逐一排序。
我可以想出一些混乱的方法,比如一个单独的历史记录表,如果需要的话可以使用列。或者甚至创建第三个列表,其中包含日期和它来自哪个列表,然后在该列表中循环,从相应的列表中选择相应的内容。不过,我觉得一定有更好的办法!
如有任何帮助,我们将不胜感激。
如果在历史项上实现GetDescription()
方法(甚至作为扩展方法),则可以执行以下操作:
db.PickingHistory.Where(ph => ph.Item.ItemId == 123)
.Select(ph => new { Time = ph.Date, Description = ph.GetDescription() })
.Concat(db.MoveHistory.Where(mh => mh.ItemId == 123)
.Select(mh => new { Time = mh.Date, Description = mh.GetDescription() })
.OrderByDescending(e => e.Time).Select(e => e.Description);
您面临的问题是,您试图将数据库模型用作显示模型,但显然失败了。您需要创建一个代表历史网格的新类,然后从各种查询中填充它。根据您的示例输出,显示模型可能是:
public class HistoryRow{
public DateTime EventDate { get; set; }
public string ItemName { get; set; }
public string Action { get; set; }
public string Detail { get; set; }
}
然后将数据加载到此显示模型中:
var historyRows = new List<HistoryRow>();
var pickingRows = _db.PickingHistory.Select(ph => new HistoryRow{
EventDate = ph.Date,
ItemName = ph.Item.Name,
Action = "picked",
Detail = "from works order " + ph.WorksOrderCode);
historyRows.AddRange(pickingRows);
var movingRows = _db.MoveHistory.Select(mh => new HistoryRow{
EventDate = mh.Date,
ItemName = ph.Item.Name,
Action = "moved",
Detail = "from location " + mh.Location1Id + " to location " + mh.Location2Id);
historyRows.AddRange(movingRows );
您可以重复添加各个表中的行,以获得HistoryRow
操作的大列表,然后根据需要对该列表进行排序并显示值。
foreach(var historyRow in historyRows)
{
var rowAsString = historyRow.ItemName + " was " + historyRow.Action.....;
Console.WriteLine(rowAsString);
}
如果您实现这一点是为了提供某种撤消/重做历史记录,那么我认为您的做法是错误的。通常,您会有一个具有相关参数值的ICommand
对象集合,例如,您存储已发生的操作。然后,您就可以为每个项目单独筛选此集合。
如果您不想实现某种撤消/重做历史记录,那么我误解了您的问题,您可以忽略它。