使用linq对实体进行分组会返回非正确的结果

时间:2013-07-08 10:50:33

标签: c# linq group-by linq-to-entities

在我最近的应用程序中,我有一个Document实体,此文档可以从用户引用到另一个用户,每个用户组也有一个DocumentStation;这些引用登录DocumentStationHistory表: enter image description here

现在,我希望列出所有最后一个文档引用DocumentStationHistory表中的Dictionary首先使用EF代码(documentId分组)。 所以我写了这些方法:

public Dictionary<int, DocumentStationHistory> GetLastDocumentStationHistoryListOfDocuments(string criteria)
{
        Dictionary<int, DocumentStationHistory> result = new Dictionary<int, DocumentStationHistory>();
        using (IUnitOfWork uow = new MyContext())
        {
            DocumentStationHistoryRepository repository = new DocumentStationHistoryRepository(uow);
            result = repository.All().
                Include(x => x.DocumentStation).
                Where(criteria,new object[]{}).
                OrderBy(d=>d.DocumentId).
                OrderBy(d=>d.DocumentStationHistoryId).
                GroupBy(g => (int)g.DocumentId).
                ToDictionary(g => (int)g.Key, g => g.LastOrDefault());
            return result;
        }
}

它返回一个字典,但结果不正确,它没有返回每个文档的最后引用,也包括DocumentStation导航属性,结果是null。 我的错在哪里?

1 个答案:

答案 0 :(得分:2)

订购的两个问题:

  • 您正在使用OrderBy两次,这几乎肯定不会达到您认为的效果。您通常应使用OrderBy,然后使用ThenBy
  • 我不相信GroupBy可以保证维持序列其余部分的顺序。您应该在分组中订购

    result = service.All()
            .Include(x => x.DocumentStation)
            .Where(criteria, new object[]{})
            .GroupBy(g => (int)g.DocumentId)
            .ToDictionary(g => (int)g.Key, 
                          g => g.OrderBy(d => d.DocumentId)
                                .ThenBy(d => d.DocumentStationHistoryId)
                                .Last());
    

(没有必要使用LastOrDefault - 至少有一个元素,否则就不会有一个组。)

使用Last的替代方法是使用OrderByDescendingThenByDescending,然后使用First

我不知道DocumentStation包含部​​分,我很害怕。