2017-09-08 5 views
0

私は、次の機能があります:私は何をしようとしているLINQクエリの結果タイプではサポートされません「System.Linq.IQueryable`1 [可能System.Int32]

public List<DTO.ArticleDTO> GetRecentArticles(int portalID, int moduleID, int domainID, int rootKnowledgeTypeID, int count) 
{ 
    var articles = 
     (from 
      article in _Context.Articles.LatestArticles(_Context.ArticleVersions, portalID, moduleID) 
      where _GetRootDomainsForArticle(article.ArticleID, article.Version, rootKnowledgeTypeID).Contains(domainID) 
     orderby article.UpdatedOn descending 
      select new ArticleDTO 
      { 
       ArticleID = article.ArticleID, 
       Title = article.Title, 
       Summary = article.Introduction, 
       Content = article.Content, 
       UpdatedOn = article.UpdatedOn, 
       Version = article.Version, 
       KnowledgeTypeText = (from 
             category in _Context.Categories 
            join 
             categoryVersion in _Context.ArticleCategoryVersions 
            on 
             category.CategoryID equals categoryVersion.CategoryID 
            where 
             categoryVersion.Version == article.Version && 
             categoryVersion.ArticleID == article.ArticleID && 
             category.ParentID == rootKnowledgeTypeID 
            select 
             category.Name 
           ).First() 
      }); 

    return articles.Take(count).ToList(); 
} 

をすべて取得することですルートカテゴリ(ドメインID)に属する記事。カテゴリはドメイン/サブドメインとみなされ、各記事は1つ以上のドメインとサブドメインに属します。ですから、私は上記のlinqクエリのwhere節で以下のメソッドを使用しています。

private IQueryable<int> _GetRootDomainsForArticle(int articleID, int version, int rootKnowledgeTypeID) 
{ 
    return from c in _Context.Categories 
        join cv in _Context.ArticleCategoryVersions on c.CategoryID equals cv.CategoryID 
        where cv.ArticleID == articleID 
        where cv.Version == version 
        where c.ParentID == null 
        where c.CategoryID != rootKnowledgeTypeID 
        select c.CategoryID; 
} 

私が手にエラーがある: "比較演算子 'はSystem.Linq.IQueryable`1 [可能System.Int32]' 型に対応していません。"

私は遅延実行のためだと思っていますが、正しい方法を理解していません。

編集:@SivaGopalコメントに基づいて

私は、メイン・クエリの一部になることを_GetRootDomainsForArticleからクエリを移動し、それが働いた:

public List<DTO.ArticleDTO> GetRecentArticles(int portalID, int moduleID, int domainID, int rootKnowledgeTypeID, int count) 
{ 
    var articles = 
     (from 
      article in _Context.Articles.LatestArticles(_Context.ArticleVersions, portalID, moduleID) 
      where (from c in _Context.Categories 
       join cv in _Context.ArticleCategoryVersions on c.CategoryID equals cv.CategoryID 
       where cv.ArticleID == article.ArticleID 
       where cv.Version == article.Version 
       where c.ParentID == null 
       where c.CategoryID != rootKnowledgeTypeID 
       select c.CategoryID).Contains(domainID) 
      orderby article.UpdatedOn descending 
      select new ArticleDTO 
      { 
       ArticleID = article.ArticleID, 
       Title = article.Title, 
       Summary = article.Introduction, 
       Content = article.Content, 
       UpdatedOn = article.UpdatedOn, 
       Version = article.Version, 
       KnowledgeTypeText = (from 
           category in _Context.Categories 
            join 
           categoryVersion in _Context.ArticleCategoryVersions 
          on 
           category.CategoryID equals categoryVersion.CategoryID 
            where 
           categoryVersion.Version == article.Version && 
           categoryVersion.ArticleID == article.ArticleID && 
           category.ParentID == rootKnowledgeTypeID 
            select 
           category.Name 
         ).First() 
      }); 

    return articles.Take(count).ToList(); 
} 

のLINQの私の限られた理解はに私を導きますそのクエリをクエリ構成の形式としてメソッドに分割し、再利用可能にすることができます。このようなことはないと思われますが、確かに、特にクエリの一部が頻繁に再利用されるようなコードを大幅に減らすため、これを行う方法が必要です。

+0

メインクエリに 'GetRootDomainsForArticle'クエリをインラインで試しましたか?また、[this so](https://stackoverflow.com/questions/1230551/comparison-operators-not-support-for-type-system-linq-iqueryable1system-int)を参考にしてください。 –

+0

実際に働いた@SivaGopal!問題はなぜですか? GetRootDomainsForArticleメソッドからのデータは他のメソッドで再利用したいので、実際にはうまくいかない理由を理解したいと思っています。 – Jacques

+0

私の理解は、実行が遅れたためです。あなたのデータベースは、どの機能を呼び出そうとしているのか分かりません。 –

答えて

0

あなたの関数をもっと分割してみてください。長くて深いLinqメソッドはうまくいくかもしれませんが、読みやすくするためにはそれほど良くなく、あなたが話しているようなバグを紹介することができます。私はまだこれをテストしていませんが、それはあなたの問題を解決するのに役立つはずです。

public List<DTO.ArticleDTO> GetRecentArticles(int portalID, int moduleID, int domainID, int rootKnowledgeTypeID, int count) 
{ 
    var allArticles = _Context.Articles.LatestArticles(_Context.ArticleVersions, portalID, moduleID); 
    var filteredArticles = new List<DTO.ArticleDTO>(); 

    foreach (DTO.ArticleDTO article in allArticles) 
    { 
     var domains = _GetRootDomainsForArticle(article.ArticleID, article.Version, rootKnowledgeTypeID); 
     if (domains.Contains(domainID) 
     { 
      filteredArticles.Add(article); 
     } 
    } 

    var articles = filteredArticles.OrderBy(article.UpdatedOn).Descending().Select(article => new DTO.ArticleDTO { 
     ArticleID = article.ArticleID, 
     Title = article.Title, 
     Summary = article.Introduction, 
     Content = article.Content, 
     UpdatedOn = article.UpdatedOn, 
     Version = article.Version, 
     KnowledgeTypeText = (from category in _Context.Categories 
              join categoryVersion in _Context.ArticleCategoryVersions 
              on category.CategoryID equals categoryVersion.CategoryID 
              where 
              categoryVersion.Version == article.Version && 
              categoryVersion.ArticleID == article.ArticleID && 
              category.ParentID == rootKnowledgeTypeID 
              select 
              category.Name 
             ).First() 
    }).Take(count).ToList(); 
} 

はまた、あなたは絶対にあなたの_GetRootDomainsForArticle関数からのIQueryable <>を返すために必要なのですか?あなたがそれを手放すことができれば、IEnumerable <>を返すようにしたいと思います。

Koda

+0

最初にこのようにデータベースからリスト全体を抽出してフィルタリングしていませんか?これは潜在的に何千もの記事になり、それらをフィルタリングする前にワイヤを移動する必要がありますか? – Jacques

+0

重要な点は問題を診断することですが、ロジックが複数レベルのlinqクエリにまとめられている間は、直面しているような問題を解決することが常に困難になります。最初に動作するコードを作ってから、やっているように最適化して、必要以上に多くのリソースを使用しないようにしてください。 – Kodaloid

+0

はあなたの意見を完全に理解していますが、私は_GetRootDomainsForArticleを呼び出すwhere節なしで他の場所で実行しているクエリを持っています。 _GetRootDomainsFOrArticleはそれ自体で動作し、あなたが示唆しているものと多少似ていますが、私はいくつかの記事を抽出していますので、ワイヤを通るトラフィックはそれほど心配していません – Jacques

関連する問題