2017-02-14 15 views
0

私はLinqを初めて使うので、長い質問のためにappologiseします。記事、カテゴリ、バージョン管理を扱う複雑なLinqクエリ

私は記事、カテゴリ、バージョン管理に関するCMSを持っています。カテゴリは階層的です(カテゴリにはParentIDがあります)。これはやや複雑な方法で使用しています。

次のようなデータ構造である:すべてのサブカテゴリ(副サブカテゴリ)と
enter image description here

カテゴリー1ドメインと考えられます。
カテゴリ2すべてのサブカテゴリは、ナレッジタイプとみなされます。

記事は、 'n +'ドメインとサブ(サブ)ドメインと 'n +'ナレッジタイプとともに作成され、関連付けられます。

例:
記事タイトル - "青少年育成"
ドメイン - 開発
サブドメイン - ユース
サブサブドメイン - 未成年者

知識Type - ベストプラクティス

何が必要なのですか
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クエリ(プロファイラを見ている)を、得ます!私は、ドメイン36に関連する記事を入手します。

クエリは複雑に見えますか?

これで、結果の記事を知識タイプと結合し、グループ化して、知識タイプ別にグループ化されたウェブサイトの記事リストを表示する必要があります。この作品のような

+0

あなたはArticle.ArticleVersions' 'などのナビゲーションプロパティを使用する必要があります。 –

答えて

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(); 



     } 
    } 



} 
+0

複雑に見える聖なるものです!私は答えを見つけたかもしれないが、私はまだテストしていると思う。私がいったん戻ってきて、それを投稿します – Jacques

+0

私のものはあなたよりも複雑ではありません。いくつかのテストデータを追加して、エラーが発生していないことを確認しました。 – jdweng