2012-09-18 122 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;