1

目前,我的数据库中有多个表,其中列略有不同,用于为项目定义不同的“历史”元素。

所以我有我的项目表;

int ItemId {get;set}
string Name {get;set}
Location Loc {get;set}    
int Quantity {get;set}

我可以对这些项目做一些事情,比如移动、增加数量、减少数量、预订给客户、“挑选”一个项目,诸如此类。所以我制作了多个“历史表”,因为它们有不同的值来保存例如

 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 日从 Location1 移动到 Location2

项目 123 于 2013 年 2 月 24 日从工单 421 中提取

我正在使用 Entity Framework、.NET 4.5、WPF 和使用 Linq 进行查询,但无法找到获取这些历史元素列表并根据它们的日期逐个排序的方法。

我可以想出一些杂乱无章的方法,比如在需要时使用带有列的单个历史表。或者甚至创建第三个列表,其中包含日期和它来自哪个列表,然后在该列表中循环,从相应列表中选择相应的内容。但是,我觉得必须有更好的方法!

任何帮助,将不胜感激。

4

3 回答 3

1

如果你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);
于 2013-08-06T16:22:32.197 回答
1

您面临的问题是您试图将数据库模型用作显示模型并且显然失败了。您需要创建一个代表您的历史网格的新类,然后从您的各种查询中填充它。从您的示例输出中,显示模型可能是:

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);
}
于 2013-08-06T16:11:57.097 回答
0

如果您正在实施此操作以提供某种撤消/重做历史记录,那么我认为您以错误的方式进行操作。通常,您将拥有一组ICommand具有相关参数值的对象,例如。您存储已发生的操作。然后,您将能够为每个项目单独过滤此集合。

如果您不想实现某种撤消/重做历史记录,那么我误解了您的问题,您可以忽略这一点。

于 2013-08-06T16:14:46.833 回答