2017-02-14 4 views
0

Ich bin neu bei Linq, also appologise für die lange Frage.Complex Linq Abfrage mit Artikeln, Kategorien und Versionierung

Ich habe ein CMS mit Artikeln, Kategorien und Versionierung. Kategorien sind hierarchisch (d. H. Kategorie hat eine ParentID) und wir verwenden sie auf eine etwas komplizierte Art und Weise.

Die Datenstruktur ist wie folgt:
enter image description here

Kategorie 1 mit all ihren Unterkategorien (und Sub-Sub-Kategorien) sind Domains betrachtet.
Kategorie 2 mit all seinen Unterkategorien werden betrachtet Wissenstypen.

Artikel werden erstellt und mit 'n +' Domains und Sub (sub) -Domains sowie 'n +' Knowledge Types assoziiert.

Beispiel:
Artikel Titel - "Jugendentwicklung"
Domain - Entwicklung
Sub-Domain - Jugend
Sub-Sub-Domain - Minderjährige

Wissen Typ - Best Practice

Was ich tun muss:
1. Zuerst eine Liste der neuesten Version Kunst extrahieren isel nach einer bestimmten Domäne gefiltert
2. Geben Sie eine Liste der Artikel zurück, die nach Wissenstyp gruppiert sind

Aufgrund der Komplexität der Tabellenstrukturen, dh mehrere Tabellen für Artikel (und Versionen), Kategorien und Artikel zu Kategorie (Versionen) Ich finde es schwierig, eine einzige Linq-Abfrage zu erstellen, um dies zu tun.

Hier ist eine Abfrage nur die neueste Version Artikel zu erhalten:

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 
           }; 

Ich erhalte 1 SQL-Abfrage (bei Profiler), das ist toll! Ich bekomme die Artikel mit Domain 36 gut verbunden.

Die Abfrage sieht jedoch gewunden aus?

Jetzt muss ich nur irgendwie die resultierenden Artikel nehmen, sie mit Wissenstypen verbinden und sie gruppieren, so dass ich eine Liste von Artikeln auf einer Website nach Wissenstyp gruppiert anzeigen kann.

+0

Sie sollten Navigationseigenschaften wie 'Article.ArticleVersions' verwenden. –

Antwort

0

wäre so etwas wie dieses Werk:

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

heiliger Mist, der kompliziert aussieht! Ich denke, ich habe eine Antwort gefunden, aber ich teste noch. Sobald ich habe, komme ich zurück und poste es – Jacques

+0

Mine ist nicht komplizierter als deins. Ich habe nur einige Testdaten hinzugefügt, um sicherzustellen, dass ich Fehler habe. – jdweng