Linq分组 - <k,v>我的&#39; V&#39;走?

时间:2017-02-14 17:02:24

标签: c# linq linq-to-sql

在以下代码中:

    var finalArticles =
        from domainArticle in articlesFoundInDomain

        join articleCategoryVersion in dbc.ArticlesCategoriesVersions
            on domainArticle.ArticleID equals articleCategoryVersion.ArticleID
        join articleCategory in dbc.ArticleCategories
            on articleCategoryVersion.CategoryID equals articleCategory.CategoryID

        where articleCategory.ParentID == 52

        group articleCategory by articleCategory.CategoryID
            into newArticleCategoryGroup

我理解group子句应该返回一个IEnumerable,其中k是Key,在本例中是CategoryID。

我认为我此时误解了Linq,因为我认为对于每个人来说都是如此。[&#39;应该有&#39; v&#39;中的文章列表,但我不了解机制或术语或其他内容。当我试图将这个陈述投射到一个新的匿名对象时,我似乎没有得到任何文章......他们在哪里?

修改 好的,所以我有一段代码正在运行,但不幸的是它多次点击SQL服务器:

var articlesAssociatedWithKnowledgeTypes =
                from categories in dbc.ArticleCategories

                join categoryVersions in dbc.ArticlesCategoriesVersions
                    on categories.CategoryID equals categoryVersions.CategoryID

                join articles in articlesFoundInGivenDomain
                    on categoryVersions.ArticleID equals articles.ArticleID

                where categories.ParentID == 52 && articles.Version == categoryVersions.Version

                select new
                {
                    ArticleID = articles.ArticleID,
                    ArticleTitle = articles.Title,
                    ArticleVersion = articles.Version,
                    CategoryID = categories.CategoryID,
                    CategoryName = categories.Name
                } into knowledgeTypesFlat
                group knowledgeTypesFlat by new { knowledgeTypesFlat.CategoryID, knowledgeTypesFlat.CategoryName } into knowledgeTypesNested
                select new
                {
                    CategoryID = knowledgeTypesNested.Key.CategoryID,
                    CategoryName = knowledgeTypesNested.Key.CategoryName,
                    Articles = knowledgeTypesNested.ToList()
                };

我认为文章上的ToList()会对其进行排序,但事实并非如此。但是,代码有效但我不确定这是否是最佳的?

3 个答案:

答案 0 :(得分:1)

分组返回IGrouping s的枚举。 IGrouping<K, V>本身实现IEnumerable<V>。将每个组视为该组中所有成员的可枚举加上额外属性Key

答案 1 :(得分:0)

在第一个查询中,您显示的是分组,第二个查询是组连接,两者都返回不同的结果。该组返回IEnumerable<IGrouping<TKey, TElement>>。要获得您期望的结果,您可以按CategoryIdCategoryName进行分组,并按照以下方式进行投放:

var finalArticles =
    from domainArticle in articlesFoundInDomain
    join articleCategoryVersion in dbc.ArticlesCategoriesVersions
        on domainArticle.ArticleID equals articleCategoryVersion.ArticleID
    join articleCategory in dbc.ArticleCategories
        on articleCategoryVersion.CategoryID equals articleCategory.CategoryID
    where articleCategory.ParentID == 52
    group articleCategory by new{ articleCategory.CategoryID,articleCategory.CategoryName}
        into g
    select new {CatId=g.Key.CategoryID, CatName=g.Key.CategoryName,Articles =g.ToList() };

如果您需要分组元素,可以像上面一样调用ToListToArray

答案 2 :(得分:0)

您的finalArticles个查询会生成IEnumerable<IGrouping<int, Article>>(假设CategoryIDint且您的文章属于Article类型。)

这些IGrouping<int, Article>提供Key类型的int属性(您的CategoryID以及表示IEnumerable<Article>文章序列的CategoryID }。

您可以将此示例转换为Dictionary<int, List<Article>>映射CategoryID到文章列表:

var dictionary = finalArticles.ToDictionary(group => group.Key, group => group.ToList());

或包含文章的类别列表:

var categories = finalArticles.Select(group => new { 
                 CategoryID = group.Key, 
                 Articles = group.ToList()}).ToList();

评论后更新:

var finalArticles =
      from domainArticle in articlesFoundInDomain
      join articleCategoryVersion in dbc.ArticlesCategoriesVersions
           on domainArticle.ArticleID equals articleCategoryVersion.ArticleID
      join articleCategory in dbc.ArticleCategories
           on articleCategoryVersion.CategoryID equals articleCategory.CategoryID

      where articleCategory.ParentID == 52

      group articleCategory by new {articleCategory.CategoryID, articleCategory.Name}
      into newArticleCategoryGroup
      select new 
      { 
          CategoryID = newArticleCategoryGroup.Key.CategoryID,
          CategoryName = newArticleCategoryGroup.Key.Name,
          Articles = newArticleCateGroup.ToList()
      }