2013-08-06 38 views
1

目前,我在我的数据库中有多个表格,其中列略有不同,为一个项目定义了不同的“历史”元素。使用Linq从多个表中排列多个列表

所以我有我的物品表;

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被移动于23/02/2013从LOCATION1到LOCATION2

项目123 421

我使用实体框架的工作秩序被挑上24/02/2013, .NET 4.5,WPF以及使用Linq进行查询,但无法想出一个方法来获取这些历史元素列表,并根据它们的日期一一列出。

我可以想到凌乱的方式,就像一个单独的历史表,如果需要使用列。甚至可以创建第三个列表,其中包含日期和来自哪个列表,然后在列表中循环选择相应列表中的相应内容。但是,我觉得必须有更好的方法!

任何帮助,将不胜感激。

回答

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); 
+0

这事我以后的那种。瑞安艾米斯可能描述了最新的解决方案,但这是我想要的。谢谢! – MichaelMcCabe

+0

任何想法为什么我得到错误 - LINQ to Entities不能识别方法'System.String GetDescription()'?我确定它与我添加到历史记录类中的描述方法有关,而实体框架不喜欢它。可能是一个不相关的问题 – MichaelMcCabe

+0

你是对的 - 它对我来说看起来非常像ESQL的问题。不幸的是,它的错误信息可能相当具有误导性。我可以建议的最简单的方法是将'GetDescription()'中的所有行注释掉,然后将它们替换为一些简单的内容,然后恢复它们直到找到故障点。最后一次遇到这种情况时,我就是这样处理ESQL的难题的。 –

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); 
} 
0

如果你是为了提供某种撤消/恢复历史中实现这一点,那么我认为你在错误的方式去了解它。通常情况下,您将拥有一个带有相关参数值的ICommand对象集合,例如。您存储已发生的操作。然后,您可以单独过滤每个项目的这个集合。

如果你不想实现某种撤消/重做历史,那么我误解了你的问题,你可以忽略它。