使用linq在没有关闭机票的最低日期订购机票?

时间:2012-03-15 16:32:57

标签: c# .net linq

我有一个名为Ticket的对象,其中包含一个名为TicketActions的对象列表。 Ticket对象有一个名为Date_Closed的字段,Actions对象有一个名为Action_Date的字段:

Ticket
   Date_Closed
   TicketActions
      -Action_Date

我要做的是根据每个动作的最新日期按照升序排序票证列表(列表),其中票证没有Date_Closed的值。目标是将此列表加载到列表视图中,并以在页面上按顺序显示票证的方式显示票证,放置那些在顶部没有操作的情况下最长的票证。这有意义吗?

到目前为止,我最终得到的结果是:

protected List<FullTicket> BuildTickets(int ticketsToShow)
{
    using (var db = new SupportLogDBDataContext())
    {
        var result =
            (from ticket in db.Support_Tickets
            join status in db.Ticket_Statuses on ticket.Status_ID equals status.ID
            select new FullTicket
            {
                TicketID = ticket.ID,
                DateOpened = (DateTime)ticket.Date_Opened,
                DateClosed = (DateTime)ticket.Date_Closed,
                Subject = ticket.Subject,
                Status = new KeyPair { Key = status.Status, Value = status.ID },
                CreatedBy = new GuidPair { Key = ticket.Reported_By, Value = (Guid)ticket.AD_GUID },
                TicketActions =
                    (from a in db.Ticket_Actions
                     where a.Ticket_ID == ticket.ID
                     select a).ToList()
            }).Take(ticketsToShow).ToList();
        result.OrderBy(i => i.TicketActions.Where(i.DateClosed == null).Max()); //error on this line (invalid arguments)
        return result;
    }        
}

4 个答案:

答案 0 :(得分:2)

人们快速回复!

试试这个:

var result = (from ticket in tickets
              where !ticket.DateClosed.HasValue
              select ticket).OrderByDescending(t => (from a in t.TicketActions
                                                     select a.ActionDate).Max());

从这里你可以根据需要选择。

答案 1 :(得分:1)

这是一些简单的代码。

var sorted = tickets.Where(t => t.DateClosed == null)
                    .OrderBy(t => t.TicketActions.Max(ta => ta.Action_Date.Ticks));

抱歉,我更喜欢LINQ函数语法,但是如果你想在查询语法中使用它,那么转换它应该不会太难。

答案 2 :(得分:1)

result.OrderBy(i => i.TicketActions.Where(i.DateClosed == null).Max()); 

此行生成错误,因为未定义TicketActions.Max()。 您需要将TicketAction投影到可以Max'd的东西。例如:

result.OrderBy(i =>
  i.TicketActions
  .Where(ta => i.DateClosed == null)
  .Select(ta => ta.Id)
  .Max()
);

另请注意:

  1. OrderBy不会修改其来源。 OrderBy 返回一个有序的IEnumerable,你没有在任何地方分配。
  2. OrderBy的可枚举是延迟的,你想要一个List结果,所以你应该调用ToList。
  3. 您正在查询之外访问Ticket.TicketActions。这将导致一个数据库往返每个票据加载该属性。

  4. 以下是对您的查询的修改,通过在查询中排序和使用导航属性来避免上述问题。

    from ticket in db.Support_Tickets
    where ticket.DateClosed == null
    let lastDate = ticket.TicketActions
      .Select(ta => ta.ActionDate)
      .OrderByDescending(date => date)
      .FirstOrDefault()
    let ticketStatus = ticket.TicketStatus
    order by lastDate
    select new FullTicket
    {
      ...
    }
    

答案 3 :(得分:1)

David B的分析略有偏差。这条线...

result.OrderBy(i => i.TicketActions.Where(i.DateClosed == null).Max());

...将无法编译,因为Where方法的参数不是lambda表达式或委托。

我会建议这个解决方案(假设TicketAction类型的相关属性是ActionDate):

return result.Where(i => i.DateClosed == null)
  .OrderBy(i => i.TicketActions.Max(a => a.ActionDate));

或者,在查询理解语法中:

return from i in result
    where i.DateClosed == null
    orderby i.TicketActions.Max(a => a.ActionDate)
    select i;