15

「Alfa 147」のような車のキーワード検索に基づいて、レコードの個別のリストを返す必要があります。

問題は、「アルファ」車が 3 台あるため、1 + 3 レコードが返されることです (アルファの場合は 1、結果の場合は 147、アルファの場合は 3 のようです)。

編集:

SQL-Server クエリは次のようになります。

SELECT DISTINCT c.Id, c.Name /*, COUNT(Number of Ads in the KeywordAdCategories table with those 2 keywords) */
FROM Categories AS c
INNER JOIN KeywordAdCategories AS kac ON kac.Category_Id = c.Id
INNER JOIN KeywordAdCategories AS kac1 ON kac.Ad_Id = kac1.Ad_Id AND kac1.Keyword_Id = (SELECT Id FROM Keywords WHERE Name = 'ALFA')
INNER JOIN KeywordAdCategories AS kac2 ON kac1.Ad_Id = kac2.Ad_Id AND kac2.Keyword_Id = (SELECT Id FROM Keywords WHERE Name = '147')

私のLINQクエリは次のとおりです。

       var query = from k in keywordQuery where splitKeywords.Contains(k.Name) 
                    join kac in keywordAdCategoryQuery on k.Id equals kac.Keyword_Id
                    join c in categoryQuery on kac.Category_Id equals c.Id
                    join a in adQuery on kac.Ad_Id equals a.Id
                    select new CategoryListByKeywordsDetailDto
                    {
                        Id = c.Id,
                        Name = c.Name,
                        SearchCount = keywordAdCategoryQuery.Where(s => s.Category_Id == c.Id).Where(s => s.Keyword_Id == k.Id).Distinct().Count(),
                        ListController = c.ListController,
                        ListAction = c.ListAction
                    };

        var searchResults = new CategoryListByBeywordsListDto();

        searchResults.CategoryListByKeywordsDetails = query.Distinct().ToList();

エンティティは次のとおりです。

public class Keyword
{
    // Primary properties
    public int Id { get; set; }
    public string Name { get; set; }
}
// Keyword Sample Data:
// 1356 ALFA
// 1357 ROMEO
// 1358 145
// 1373 147

public class Category
{
    // Primary properties
    public int Id { get; set; }
    public string Name { get; set; }
}
// Category Sample Data
// 1    NULL    1   Carros
// 2    NULL    1   Motos
// 3    NULL    2   Oficinas
// 4    NULL    2   Stands
// 5    NULL    1   Comerciais
// 8    NULL    1   Barcos
// 9    NULL    1   Máquinas
// 10   NULL    1   Caravanas e Autocaravanas
// 11   NULL    1   Peças e Acessórios
// 12   1   1   Citadino
// 13   1   1   Utilitário
// 14   1   1   Monovolume

public class KeywordAdCategory
{
    [Key]
    [Column("Keyword_Id", Order = 0)]
    public int Keyword_Id { get; set; }

    [Key]
    [Column("Ad_Id", Order = 1)]
    public int Ad_Id { get; set; }

    [Key]
    [Column("Category_Id", Order = 2)]
    public int Category_Id { get; set; }
}
// KeywordAdCategory Sample Data
// 1356 1017    1
// 1356 1018    1
// 1356 1019    1
// 1357 1017    1
// 1357 1018    1
// 1357 1019    1
// 1358 1017    1
// 1373 1019    1

 public class Ad
{
    // Primary properties
    public int Id { get; set; }
    public string Title { get; set; }
    public string TitleStandard { get; set; }
    public string Version { get; set; }
    public int Year { get; set; }
    public decimal Price { get; set; }

    // Navigation properties
    public Member Member { get; set; }
    public Category Category { get; set; }
    public IList<Feature> Features { get; set; }
    public IList<Picture> Pictures { get; set; }
    public IList<Operation> Operations { get; set; }
}

public class AdCar : Ad
{
    public int Kms { get; set; }
    public Make Make { get; set; }
    public Model Model { get; set; }
    public Fuel Fuel { get; set; }
    public Color Color { get; set; }
}
// AdCar Sample Data
// 1017 Alfa Romeo 145 1.6TDI 2013  ALFA ROMEO 145 1.6TDI 2013  12  2       1.6TDI  1000    1   2013    1   20000,0000  2052    AdCar
// 1018 Alfa Romeo 146 1.6TDI 2013  ALFA ROMEO 146 1.6TDI 2013  12  2   5   1.6TDI  1000    2   2013    1   20000,0000  2052    AdCar
// 1019 Alfa Romeo 147 1.6TDI 2013  ALFA ROMEO  147 1.6TDI 2013 12  2   6   1.6TDI  1000    3   2013    1   20000,0000  2052    AdCar

「ALFA」の検索結果は「Cars: 3」で、「ALFA 147」の検索結果は「Cars: 1」で、実際に得られる結果は「Cars: 1 \n Cars: 3」です。

4

12 に答える 12

6

kac は単語をフィルタリングしていません... したがって、この kac、kac1、および kac2 の結合は 3 行を返します。これは、この広告のキーワードの数であるためです。

あなたはそれを削除する必要があります..

これを試して:

SELECT DISTINCT 
    c.Id, c.Name /*, COUNT(Number of Ads in the KeywordAdCategories table    with those 2 keywords) */
FROM 
    Categories AS c
INNER JOIN 
    KeywordAdCategories AS kac1 ON kac1.Keyword_Id = (SELECT Id 
                                                      FROM Keywords 
                                                      WHERE Name = 'ALFA')
                                AND kac1.Category_Id = c.Id
INNER JOIN 
    KeywordAdCategories AS kac2 ON kac1.Ad_Id = kac2.Ad_Id 
                                AND kac2.Keyword_Id = (SELECT Id 
                                                       FROM Keywords 
                                                       WHERE Name = '147')
                                AND kac2.Category_Id = c.Id

私はテストをしました...

アンビエントを次のように設定する

    declare @Keywords table(id int,name varchar(max))
    insert into @Keywords(id,name)
    values (1356,'ALFA')
    ,(1357,'ROMEO')
    ,(1358,'145')
    ,(1373,'147')

    declare @Categories table(id int, name varchar(max))
    insert into @Categories(id,name)
    values (1,'Carros')
    ,(2,'Motos')


    declare @KeywordAdCategories table(Keyword_Id int, ad_Id int,Category_Id int)
    insert into @KeywordAdCategories (Keyword_Id , ad_Id,Category_Id)
    values (1356, 1017,1)
    ,(1356, 1018,1)
    ,(1356, 1019,1)
    ,(1357, 1017,1)
    ,(1357, 1018,1)
    ,(1357, 1019,1)
    ,(1358, 1017,1)
    ,(1373, 1019,1)

次の 2 つのクエリを実行します。

--query 1
SELECT 
    c.Id, c.Name,COUNT(*) as [count]
FROM 
    @Categories AS c
INNER JOIN 
    @KeywordAdCategories AS kac1 ON kac1.Keyword_Id = (SELECT Id 
                                                       FROM @Keywords 
                                                       WHERE Name = 'ALFA')
                                 AND kac1.Category_Id = c.Id
GROUP BY 
    c.Id, c.Name

私はこの結果セットを取得します:

  Id          Name       count
  ----------- ---------- -----------
  1           Carros     3

そして、2 つの単語に対する 2 番目のクエリ...

--query 2
SELECT 
    c.Id, c.Name,COUNT(*) as [count]
FROM 
    @Categories AS c
INNER JOIN 
    @KeywordAdCategories AS kac1 ON kac1.Keyword_Id = (SELECT Id 
                                                       FROM @Keywords 
                                                       WHERE Name = 'ALFA')
                                 AND kac1.Category_Id = c.Id
INNER JOIN 
    @KeywordAdCategories AS kac2 ON kac1.Ad_Id = kac2.Ad_Id 
                                 AND kac2.Keyword_Id = (SELECT Id 
                                                        FROM @Keywords 
                                                        WHERE Name = '147')
                                 AND kac2.Category_Id = c.Id
GROUP BY
    c.Id, c.Name

結果セットは次のとおりです。

 Id          Name       count
 ----------- ---------- -----------
 1           Carros     1

これは、あなたの望むことですか?

于 2013-01-25T10:49:15.160 に答える
4

Distinct()メソッドを使用できます。

var query = ...
var query = query.Distinct();

このコードは個別の値を返しますを参照してください。ただし、詳細については、匿名型ではなく、強く型付けされたコレクションを返す必要があります。

于 2013-01-14T18:57:53.047 に答える
3

クエリ文字列を配列に分割し、各キーワードについてデータベースにクエリを実行し、unionsを使用して結果セットを結合することを繰り返します。結果のセットは、指定されたキーワードのいずれかに一致するすべての個別のレコードになります。

于 2013-01-26T08:03:00.843 に答える
2

多分これは近いですか?少なくともサブクエリは、あなたが作業できるように少し開いています。

var query =
  from c in categoryQuery
  let keywords =
  (
    from k in keywordQuery where splitKeywords.Contains(k.Name)
    join kac in keywordAdCategoryQuery on k.Id equals kac.Keyword_Id
    where kac.Category_Id == c.Id
    join a in adQuery on kac.Ad_Id equals a.Id
    select k.Id
  ).Distinct()
  where keywords.Any()
  select new CategoryListByKeywordsDetailDto
  {
    Id = c.Id,
    Name = c.Name,
    SearchCount =
    (
      from kac in keywordAdCategoryQuery
      where kac.Category_Id == c.Id
      join kId in keywords on kac.Keyword_Id equals kId
      select kac.Id
    ).Distinct().Count(),
    ListController = c.ListController,
    ListAction = c.ListAction
  };
于 2013-01-15T01:41:56.973 に答える
2

それで、私がその必要性を正しく理解していれば、あなたは、今取得している OR マッチングではなく、すべての単語のサブセットをテキストで一致させたいですか? 少なくとも 2 つのオプションがありますが、最初のオプションは分割を SQL に変換できない可能性があります。

var query = from k in keywordQuery where !splitKeywords.Except(k.Name.split(' ')).Any()

これにより、次の仮定が成り立ちます。

  1. キーワード内の単語はスペースで区切られています。
  2. 部分一致ではなく完全一致を探しています。(つまり、Test は TestTest と一致しません)。

もう1つのオプションは、述語ビルダーを使用して述語を動的に生成することです(しばらくこれを行っていません。私の実装には微調整が必​​要かもしれません-しかし、これはより可能性の高い(そして私の考えではより良い)解決策です):

var predicate = PredicateBuilder.True<keywordQuery>();
foreach (string s in splitKeywords) {
    predicate.AND(s.Contains(k.Name));
}

query.Where(predicate);

私の構文の一部がオフになっている場合、誰かがコメントできれば幸いです。編集: 述語ビルダーに関する適切なリファレンスへのリンクを含む: http://www.albahari.com/nutshell/predicatebuilder.aspx

アップデート

誰かがそれを行う方法を探してここに来た場合は、複数のテーブルにまたがる述語ビルダー。 PredicateBuilder は複数のテーブルにまたがる述語を生成できますか?

于 2013-01-22T16:47:44.450 に答える
2

linq の優れた機能の 1 つは、複雑なクエリをより小さく簡単な手順で作成し、それらを結合する方法を linq に任せることができることです。

以下は、この情報を取得する 1 つの方法です。これが最適かどうかはわかりませんが、複数のキーワードを選択した場合のパフォーマンスを確認する必要があります。

キーワードが次のように定義されていると仮定します

var keywords = "Alfa 147";
var splitKeywords = keywords.Split(new char[] {' '});

ステージ1

広告とカテゴリでグループ化されたキーワードのリストを取得し、

var subQuery = (from kac in keywordAdCategoryQuery  
    join k in keywordQuery  on kac.Keyword_Id equals k.Id 
    select new 
    {        
        kac.Ad_Id, 
        kac.Category_Id, 
        KeyWord = k.Name, 
    }); 

var grouped = (from r in subQuery 
    group r by new { r.Ad_Id, r.Category_Id}  into results
    select new 
    { 
        results.Key.Ad_Id , 
        results.Key.Category_Id , 
        keywords = (from r in results select r.KeyWord) 
    });

投稿したクラスは、データベースにテーブル間で外部キー関係が定義されていないことを示唆していることに注意してください。もしそうなら、この段階は書くのが少し簡単になるでしょう。

ステージ 2

各キーワードを持たないグループを除外します

foreach(var keyword in splitKeywords)
{
    var copyOfKeyword = keyword ;   // Take copy of keyword to avoid closing over loop
    grouped = (from r in grouped where r.keywords.Contains(copyOfKeyword) select r) ;
}

ステージ3

カテゴリ別にグループ化し、カテゴリごとに結果を数えます

var groupedByCategories = (from r in grouped 
    group r by r.Category_Id into results 
    join c in categoryQuery  on results.Key equals c.Id 
    select new 
    { 
        c.Id , 
        c.Name , 
        Count = results.Count()
    });

ステージ4

次に、SQL から情報を取得します。これは、すべて 1 つのクエリで実行する必要があります。

var finalResults = groupedByCategories.ToList();
于 2013-01-23T11:23:16.473 に答える
2

キーワードごとにクエリを実行してから、結果セットを結合できる必要があります。重複する値はユニオンから削除され、必要な集計を行うことができます。

于 2013-01-24T00:46:29.653 に答える
1

選択しながらクラスを削除してみてください

 var query = (from k in keywordQuery where splitKeywords.Contains(k.Name) 
                        join kac in keywordAdCategoryQuery on k.Id equals kac.Keyword_Id
                        join c in categoryQuery on kac.Category_Id equals c.Id
                        join a in adQuery on kac.Ad_Id equals a.Id
                        select new
                        {
                            Id = c.Id,
                            Name = c.Name,
                            SearchCount = keywordAdCategoryQuery.Where(s => s.Category_Id == c.Id).Where(s => s.Keyword_Id == k.Id).Distinct().Count(),
                            ListController = c.ListController,
                            ListAction = c.ListAction
                        }).Distinct().ToList();

        var searchResults = new CategoryListByBeywordsListDto();



searchResults.CategoryListByKeywordsDetails = (from q in query select new           CategoryListByKeywordsDetailDto
{
                        Id = q.Id,
                        Name = q.Name,
                        SearchCount = q.SearchCount,
                        ListController = q.ListController,
                        ListAction = q.ListAction
                    }).ToList();
于 2013-01-23T04:31:23.793 に答える
1

LINQを使用してメモリコレクションに対して直接これを試しました(SQLを介さずに)-私にとってはうまくいくようです(主なポイントは、指定されたすべてのキーワードに適用される広告を検索したいということです。とにかく、以下のいくつかのサンプルコード(少しコメントっぽく、必ずしも最も効率的ではありませんが、うまくいけばポイントを示しています...)

次の「データセット」の操作:

private List<AdCar> AdCars = new List<AdCar>();
private List<KeywordAdCategory> KeywordAdCategories = new List<KeywordAdCategory>();
private List<Category> Categories = new List<Category>();
private List<Keyword> Keywords = new List<Keyword>();

提供したデータを使用してテストメソッドに入力されます...

検索方法は次のようになります。

var splitKeywords = keywords.Split(' ');

var validKeywords = Keywords.Join(splitKeywords, kwd => kwd.Name.ToLower(), spl => spl.ToLower(), (kwd, spl) => kwd.Id).ToList();

var groupedAdIds = KeywordAdCategories
                .GroupBy(kac => kac.Ad_Id)
                .Where(grp => validKeywords.Except(grp.Select(kac => kac.Keyword_Id)).Any() == false)
                .Select(grp => grp.Key)
                .ToList();

var foundKacs = KeywordAdCategories
    .Where(kac => groupedAdIds.Contains(kac.Ad_Id))
    .GroupBy(kbc => kbc.Category_Id, kac => kac.Ad_Id);

//Results count by category
var catCounts = Categories
    .Join(foundKacs, cat => cat.Id, kacGrp => kacGrp.Key, (cat, kacGrp) => new { CategoryName = cat.Name, AdCount = kacGrp.Distinct().Count() })
    .ToList();

//Actual results set
var ads = AdCars.Join(groupedAdIds, ad => ad.Id, grpAdId => grpAdId, (ad, grpAdId) => ad);

私が言ったように、これはもっと説明するためのものです。Joins&GroupByなどの使用をあまり詳しく見ないでください(正確には、「最適」かどうかはわかりません)

したがって、上記を使用して、「Alfa」を検索すると3つの広告結果が得られ、「Alfa147」を検索すると1つの結果しか得られません。

編集:2つの可能な結果を​​表すようにコードを変更しました(あなたの質問でどちらが必要かわからなかったため)

ads検索によって返された実際の広告が表示されます

catCountsカテゴリ別の広告の数として検索結果を表す匿名タイプのリストが表示されます

これは役に立ちますか?

于 2013-02-13T08:46:16.717 に答える
1

こんにちは、私があなたの問題を正しく理解していれば

「問題は、「アルファ」車が 3 台あるため、1 + 3 レコードが返されることです (アルファの結果は 1 で、結果は 147 で、アルファの結果は 3 のようです)。

Linqは実際には必要ありません新しいプロジェクトとしてテストするだけで必要なものがあるかもしれません

    public Linqfilter()
    {
        //as Note: I modified a few classes from you because i doesn'T have your Member, Operation, Make,... classes

        #region declaration
        var originalAdCarList = new List<AdCar>() 
        {
            new AdCar(){Id=1017, Title= "Alfa Romeo 145 1.6TDI 2013", Category= new Category(){Id =12}} ,
            new AdCar(){Id=1018, Title= "Alfa Romeo 146 1.6TDI 2013", Category= new Category(){Id =11}} ,
            new AdCar(){Id=1019, Title= "Alfa Romeo 147 1.6TDI 2013", Category= new Category(){Id =12}} 
        };

        var originalKeywordAdCategoryList = new List<KeywordAdCategory>() 
        {
            new KeywordAdCategory() { Keyword_Id=1356, Ad_Id=1017,Category_Id=1},
            new KeywordAdCategory() { Keyword_Id=1356, Ad_Id=1018,Category_Id=1},
            new KeywordAdCategory() { Keyword_Id=1356, Ad_Id=1019,Category_Id=1},
            new KeywordAdCategory() { Keyword_Id=1357, Ad_Id=1017,Category_Id=1},
            new KeywordAdCategory() { Keyword_Id=1357, Ad_Id=1018,Category_Id=1},
            new KeywordAdCategory() { Keyword_Id=1357, Ad_Id=1019,Category_Id=1},
            new KeywordAdCategory() { Keyword_Id=1358, Ad_Id=1017,Category_Id=1},
            new KeywordAdCategory() { Keyword_Id=1373, Ad_Id=1019,Category_Id=1}            
        };

        var originalCategoryList = new List<Category>()
        {
            new Category(){Id=1,    Name="NULL    1   Carros"},
            new Category(){Id=2,    Name="NULL    1   Motos"},
            new Category(){Id=3,    Name="NULL    2   Oficinas"},
            new Category(){Id=4 ,   Name="NULL    2   Stands"},
            new Category(){Id=5 ,   Name="NULL    1   Comerciais"},
            new Category(){Id=8,    Name="NULL    1   Barcos"},
            new Category(){Id=9 ,   Name="NULL    1   Máquinas"},
            new Category(){Id=10 ,  Name="NULL    1   Caravanas e Autocaravanas"},
            new Category(){Id=11 ,  Name="NULL    1   Peças e Acessórios"},
            new Category(){Id=12 ,  Name="1   1   Citadino"},
            new Category(){Id=13 ,  Name="1   1   Utilitário"},
            new Category(){Id=14 ,  Name="1   1   Monovolume"}
        };


        var originalKeywordList = new List<Keyword>() 
        {
             new Keyword(){Id=1356 ,Name="ALFA"},
             new Keyword(){Id=1357 ,Name="ROMEO"},
             new Keyword(){Id=1358 ,Name="145"},
             new Keyword(){Id=1373 ,Name="147"}
        };
        #endregion declaration

        string searchText = "ALFA";

        // split the string searchText in an Array of substrings
        var splitSearch = searchText.Split(' '); 


        var searchKeyList =new List<Keyword>();

        // generate a list of Keyword based on splitSearch
        foreach (string part in splitSearch)
            if(originalKeywordList.Any(key => key.Name == part))
                searchKeyList.Add(originalKeywordList.First(key => key.Name == part));

        // generate a list of KeywordAdCategory  based on searchKList
        var searchKACList = new List<KeywordAdCategory>();
        foreach(Keyword key in searchKeyList)
            foreach (KeywordAdCategory kAC in originalKeywordAdCategoryList.Where(kac => kac.Keyword_Id == key.Id))
                searchKACList.Add(kAC);


        var groupedsearchKAClist = from kac in searchKACList group kac by kac.Keyword_Id;

        var listFiltered = new List<AdCar>(originalAdCarList);

        //here starts the real search part
        foreach (IGrouping<int, KeywordAdCategory> kacGroup in groupedsearchKAClist)
        {

            var listSingleFiltered = new List<AdCar>();
            //  generate a list of AdCar that matched the current KeywordAdCategory filter
            foreach (KeywordAdCategory kac in kacGroup)
                foreach (AdCar aCar in originalAdCarList.Where(car => car.Id == kac.Ad_Id))
                    listSingleFiltered.Add(aCar);

            var tempList = new List<AdCar>(listFiltered);
            // iterrates over a temporary copie of listFiltered and removes items which don't match to the current listSingleFiltered
            foreach (AdCar aC in tempList)
                if (!listSingleFiltered.Any(car => car.Id == aC.Id))
                    listFiltered.Remove(aC);
        }

        var AdCarCount = listFiltered.Count; // is the count of the AdCar who match

        var CatDic =new  Dictionary<Category, int>(); // will contain the Counts foreach Categorie > 0

        foreach(AdCar aCar in listFiltered)
            if(originalCategoryList.Any(cat => cat.Id ==aCar.Category.Id))
            {
                var selectedCat = originalCategoryList.First(cat => cat.Id == aCar.Category.Id);
                if (!CatDic.ContainsKey(selectedCat))
                {
                    CatDic.Add(selectedCat, 1);//new Category Countvalue
                }
                else
                {
                    CatDic[selectedCat]++; //Category Countvalue +1
                }
            }
    }
}

public class Keyword
{
    // Primary properties
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Category
{
    // Primary properties
    public int Id { get; set; }
    public string Name { get; set; }
}

public class KeywordAdCategory
{
    //[Key]
    //[Column("Keyword_Id", Order = 0)]
    public int Keyword_Id { get; set; }

    //[Key]
    //[Column("Ad_Id", Order = 1)]
    public int Ad_Id { get; set; }

    //[Key]
    //[Column("Category_Id", Order = 2)]
    public int Category_Id { get; set; }
}

public class Ad
{
    // Primary properties
    public int Id { get; set; }
    public string Title { get; set; }
    public string TitleStandard { get; set; }
    public string Version { get; set; }
    public int Year { get; set; }
    public decimal Price { get; set; }

    // Navigation properties
    public string Member { get; set; }
    public Category Category { get; set; }
    public IList<string> Features { get; set; }
    public IList<int> Pictures { get; set; }
    public IList<string> Operations { get; set; }
}

public class AdCar : Ad
{
    public int Kms { get; set; }
    public string Make { get; set; }
    public int Model { get; set; }
    public int Fuel { get; set; }
    public int Color { get; set; }
}

うまくいけば、それはあなたや他の誰かを助けるでしょう

編集:

Linqfilter()要求に答えるために Methode を拡張しました

編集2:

私はそれがまさにあなたが探しているものであるべきだと思います

        var selectedKWLinq = from kw in originalKeywordList
                             where splitSearch.Contains(kw.Name) 
                             select kw;

        var selectedKACLinq = from kac in originalKeywordAdCategoryList
                              where selectedKWLinq.Any<Keyword>(item => item.Id == kac.Keyword_Id) 
                              group kac by kac.Keyword_Id into selectedKAC
                              select selectedKAC;

        var selectedAdCar = from adC in originalAdCarList
                           where (from skAC in selectedKACLinq
                                      where skAC.Any(kac => kac.Ad_Id == adC.Id)
                                  select skAC).Count() == selectedKACLinq.Count()
                           select adC;


        var selectedCategorys = from cat in originalCategoryList
                                join item in selectedAdCar
                                on cat.Id equals item.Category.Id
                                group cat by cat.Id into g
                                select g;

        //result part
        var AdCarCount = selectedAdCar.Count(); 

        List<IGrouping<int, Category>> list = selectedCategorys.ToList(); 
        var firstCategoryCount = list[0].Count();
        var secoundCategoryCount = list[1].Count();
于 2013-02-11T13:22:31.610 に答える
0

フィーウ、これは頭がおかしい。クエリをいくつかに分割しましたが、最後に全体として実行されます (var result)。そして、匿名クラスを返しましたが、意図は明らかです。

解決策は次のとおりです。

var keywordIds = from k in keywordQuery
                    where splitKeywords.Contains(k.Name)
                    select k.Id;

var matchingKac = from kac in keywordAdCategories
            where keywordIds.Contains(kac.Keyword_Id)
            select kac;

var addIDs = from kac in matchingKac
                group kac by kac.Ad_Id into d
                where d.Count() == splitKeywords.Length
                select d.Key;

var groupedKac = from kac in keywordAdCategoryQuery
                where addIDs.Contains(kac.Ad_Id)
                group kac by new { kac.Category_Id, kac.Ad_Id };

var result = from grp in groupedKac
                group grp by grp.Key.Category_Id into final
                join c in categoryQuery on final.Key equals c.Id
                select new
                {
                    Id = final.Key,
                    Name = c.Name,
                    SearchCount = final.Count()
                };

// here goes result.ToList() or similar
于 2013-02-14T00:03:32.180 に答える