复杂的Linq查询处理文章,类别和版本控制

时间:2017-02-14 15:29:47

标签: c# linq linq-to-sql linq-to-entities

我是Linq的新手,所以我为长期问题道歉。

我有一个包含文章,类别和版本控制的CMS。类别是分层的(即Category有一个ParentID),我们以稍微复杂的方式使用它。

数据结构如下:
enter image description here

第1类及其所有子类别(和子子类别)均被视为
第2类及其所有子类别均被视为知识类型

将创建文章并与“n +”域和子(子)域以及“n +”知识类型相关联。

示例:
文章标题 - “青年发展”
领域 - 发展
子域名 - 青年人 子域 - 未成年人

知识类型 - 最佳实践

我需要做什么
 1.首先提取由给定域筛选的最新版本文章列表  2.其次,返回按知识类型

分组的文章列表

由于表结构的复杂性,即文章(和版本),类别和文章到类别(版本)的多个表,我发现很难想出一个单独的linq查询来执行此操作。

以下是获取最新版本文章的查询:

var articleGroups = from article in _Context.Articles
                                join articleVersion in _Context.ArticleVersions
                                    on article.ArticleID equals articleVersion.ArticleID
                                join articleCategoryVersion in _Context.ArticlesCategoriesVersions
                                    on articleVersion.ArticleID equals articleCategoryVersion.ArticleID
                                where articleCategoryVersion.CategoryID == 36
                                join articleCategory in _Context.ArticleCategories
                                    on articleCategoryVersion.CategoryID equals articleCategory.CategoryID
                                group articleVersion by article.ArticleID into articleGroup
                                select articleGroup.OrderByDescending(x => x.Version).First() into articleOut
                                select new
                                {
                                    ArticleID = articleOut.ArticleID,
                                    ArticleVersion = articleOut.Version,
                                    Title = articleOut.Title
                                };

我得到1个SQL查询(查看探查器),这太棒了!我收到与Domain 36相关的文章,很好。

但查询看起来很复杂?

现在,我只需要以某种方式获取结果文章,将它们与知识类型相结合并对它们进行分组,以便我可以在按知识类型分组的网站上显示文章列表。

1 个答案:

答案 0 :(得分:0)

这样的事情会起作用吗?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication1
{
    class Program
    {

        static void Main(string[] args)
        {
            DataTable Articles = new DataTable();
            Articles.Columns.Add("ArticleID", typeof(int));

            Articles.Rows.Add(new object[] { 1 });
            Articles.Rows.Add(new object[] { 2 });
            Articles.Rows.Add(new object[] { 3 });
            Articles.Rows.Add(new object[] { 4 });

            DataTable ArticleVersions = new DataTable();
            ArticleVersions.Columns.Add("ArticleID", typeof(int));
            ArticleVersions.Columns.Add("Version", typeof(string));
            ArticleVersions.Columns.Add("Title", typeof(string));

            ArticleVersions.Rows.Add(new object[] { 1, "a", "abc" });
            ArticleVersions.Rows.Add(new object[] { 1, "b", "def" });
            ArticleVersions.Rows.Add(new object[] { 1, "a", "ghi" });
            ArticleVersions.Rows.Add(new object[] { 1, "c", "jkl" });
            ArticleVersions.Rows.Add(new object[] { 2, "a", "mno" });
            ArticleVersions.Rows.Add(new object[] { 2, "b", "pqr" });
            ArticleVersions.Rows.Add(new object[] { 2, "a", "stu" });
            ArticleVersions.Rows.Add(new object[] { 3, "c", "vwx" });
            ArticleVersions.Rows.Add(new object[] { 4, "a", "yz" });
            ArticleVersions.Rows.Add(new object[] { 4, "b", "acd" });
            ArticleVersions.Rows.Add(new object[] { 4, "a", "ghi" });
            ArticleVersions.Rows.Add(new object[] { 4, "c", "nop" });

            DataTable ArticleCategoriesVersions = new DataTable();
            ArticleCategoriesVersions.Columns.Add("ArticleID", typeof(int));
            ArticleCategoriesVersions.Columns.Add("CategoryID", typeof(int));

            ArticleCategoriesVersions.Rows.Add(new object[] { 1,  10 });
            ArticleCategoriesVersions.Rows.Add(new object[] { 1,  11 });
            ArticleCategoriesVersions.Rows.Add(new object[] { 1,  12 });
            ArticleCategoriesVersions.Rows.Add(new object[] { 1,  21 });
            ArticleCategoriesVersions.Rows.Add(new object[] { 1,  22 });
            ArticleCategoriesVersions.Rows.Add(new object[] { 1,  35 });
            ArticleCategoriesVersions.Rows.Add(new object[] { 1,  36 });
            ArticleCategoriesVersions.Rows.Add(new object[] { 1,  37 });

            DataTable ArticleCategories = new DataTable();
            ArticleCategories.Columns.Add("CategoryID", typeof(int));
            ArticleCategories.Columns.Add("Name", typeof(string));

            ArticleCategories.Rows.Add(new object[] { 10, "article1" });
            ArticleCategories.Rows.Add(new object[] { 36, "article2" });
            ArticleCategories.Rows.Add(new object[] { 36, "article3" });
            ArticleCategories.Rows.Add(new object[] { 36, "article4" });
            ArticleCategories.Rows.Add(new object[] { 36, "article5" });
            ArticleCategories.Rows.Add(new object[] { 36, "article6" });
            ArticleCategories.Rows.Add(new object[] { 36, "article1" });

            var results = (from acv in ArticleCategoriesVersions.AsEnumerable()
                           where acv.Field<int>("CategoryID") == 36
                           join ac in ArticleCategories.AsEnumerable() on acv.Field<int>("CategoryID") equals ac.Field<int>("CategoryID")
                           join av in ArticleVersions.AsEnumerable() on acv.Field<int>("ArticleID") equals av.Field<int>("ArticleID")
                           join a in Articles.AsEnumerable() on av.Field<int>("ArticleID") equals a.Field<int>("ArticleID")
                           select new { acv = acv, ac = ac, av = av, a = a })
                           .GroupBy(x => x.av.Field<int>("ArticleID"))
                           .OrderByDescending(x => x.Key)
                           .Select(x => new {
                               Category1 = x.Where(y => y.av.Field<int>("ArticleID") == 36).Select(y => new { acv = y.acv, ac = y.ac, av = y.av, a = y.a}).ToList(),
                               Category2 = x.GroupBy(y => y.ac.Field<int>("CategoryID"), z => z).ToDictionary(y => y.Key, z => x.ToList()) 
                           }).ToList();



        }
    }



}