2012-09-18 80 views
3

我有以下有序鲜明

IList<Project> projects = (from update in dbContext.TicketUpdates 
       where update.TicketUpdatesEmployeeID == Profile.EmployeeID 
       orderby update.TicketUpdatesEndDate descending 
       select update.Ticket.Project).Distinct().ToList(); 

我明白Distinct()不保证顺序,但因为投影失去了我“米使用订购的领域,我不能事后重新排序。我怎样才能解决此

回答

1

我认为最好的办法是到后期处理,以维护排序:

var projects = (from update in dbContext.TicketUpdates 
      where update.TicketUpdatesEmployeeID == Profile.EmployeeID 
      orderby update.TicketUpdatesEndDate descending 
      select update.Ticket.Project); 
var seen = new HashSet<Project>(); 
foreach (var project in projects) 
{ 
    if (seen.Add(project)) 
    { 
     // A distinct project 
    } 
} 

,或者你可以滥用GroupBy

var projects = dbContext.TicketUpdates 
    .Where(uu => uu.TicketUpdatesEmployeeID == Profile.EmployeeID) 
    .GroupBy(uu => uu.Ticket.Project) 
    .OrderByDescending(gg => gg.Max(uu => uu.TicketUpdatesEndDate)) 
    .Select(gg => gg.Key); 

通过使用GroupBy跨越uu.Ticket.Project每次更新都会通过它们的相关项目进行分组。如果您有10个项目和30个更新,他们将在该阶段的输出中有10个组 - 每个项目一个组。接下来,我们按照他们最新的结束日期排序,这些日期保留了您要查找的降序。最后,我们从每个IGrouping这个项目中选择密钥。

+0

我用'GroupBy'因为我发现它更合理。你还会介意解释'GroupBy'是如何工作的吗?我现在从搜索中了解它,但是当我问这个问题时,我并不知道这些功能,而且我认为这将有助于未来的观众理解。 – ricksmt

1

使用的GroupBy新的解决方案
更新: 其实有一个更简单的解决方案:

IList<Project> projects = (from update in dbContext.TicketUpdates where update.TicketUpdatesEmployeeID == Profile.EmployeeID) 
    .GroupBy(tu=>tu.Ticket.Project) 
    .Select(group=>group.First()) 
    .OrderByDescending(tu=>tu.TicketUpdatesEndDate) 
    .Select(tu=>tu.Ticket.Project) 
    .ToList(); 

(我只是看到我在写这一点的同时,其他人发布类似的答案),使用自定义的IEqualityComparer


旧的解决方案(我不知道这是否会与LINQ2SQL工作)

有一个Distinct overload that takes a custom IEqualityComparer。因此,请使用自定义的IEqualityComparer,,然后投影您的数据,然后执行与TicketUpdates的区别。

的的IEqualityComparer应该算作所有TicketUpdates作为平等的,如果它们具有相同的项目。这样,具有相同项目的TicketUpdates将被丢弃。

(请注意,你不控制 TicketUpdates同一个项目将被丢弃。所以,如果这些TicketUpdates同一个项目有不同的EndDates,就需要涉及的GroupBy,而不是一个解决方案。

IList<Project> projects = (from update in dbContext.TicketUpdates where update.TicketUpdatesEmployeeID == Profile.EmployeeID) 
    .Distinct(new ProjectComparer()) 
    .OrderByDescending(tu=>tu.TicketUpdatesEndDate) 
    .Select(tu=>tu.Ticket.Project) 
    .ToList(); 


// Your comparer should look somewhat like this 
// (untested code! And I do not know all the details about your class structure) 
class ProjectComparer : IEqualityComparer<TicketUpdates> 
{ 
    // Products are equal if their names and product numbers are equal. 
    public bool Equals(TicketUpdates x, TicketUpdates y) 
    { 

     //Check whether the compared objects reference the same data. 
     if (Object.ReferenceEquals(x, y)) return true; 

     //Check whether any of the compared objects is null. 
     if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) 
      return false; 

     //Check whether projects are equal. 
     //(perhaps do a null check for Ticket!) 
     return x.Ticket.Project== y.Ticket.Project; 
    } 

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects. 

    public int GetHashCode(TicketUpdates x) 
    { 
     //Check whether the object is null 
     if (Object.ReferenceEquals(x, null)) return 0; 

     // null check for Ticket and Project? 
     return x.Ticket.Project.GetHashCode(); 
    } 

} 
0

您可以使用运营商的GroupBy获取唯一的记录,然后通过在新的记录做一个订单。

var projectList = dbContext.TicketUpdates.GroupBy(p => p.TicketUpdatesEmployeeId) 
        .Where(r => r.TicketUpdatesEmployeeId == Profile.EmployeeId) 
        .Select(r => r.First()) 
        .OrderByDesc(q => q.TicketUpdatesEndDate) 
        .Select(n => n.First()).Ticket.Project;