4

このクエリを linq c# コードに変換するにはどうすればよいですか。

SELECT k1.Ad_Id FROM KeywordAdCategories k1, KeywordAdCategories k2
WHERE k1.Keyword_Id =  (SELECT Id FROM keywords WHERE name = 'ALFA')
AND k2.Keyword_Id = (SELECT Id FROM keywords WHERE name = '145')
AND k1.Ad_Id = k2.Ad_Id

アイデアは、N になる可能性のあるキーワードの数に基づいて動的クエリを作成することです (例では、それらは 2: ALFA と 145 です)。

ありがとう

編集:

KeywordAdCategory モデル:

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 Keyword
{
    // Primary properties
    public int Id { get; set; }
    public string Name { get; set; }
}

キーワードが 5 つあれば、次のようになります。

SELECT k1.Ad_Id FROM KeywordAdCategories k1, KeywordAdCategories k2, KeywordAdCategories k3, KeywordAdCategories k4, KeywordAdCategories k5
WHERE k1.Keyword_Id =  (SELECT Id FROM keywords WHERE name = 'KEYWORD1')
AND k2.Keyword_Id = (SELECT Id FROM keywords WHERE name = 'KEYWORD2')
AND k1.Ad_Id = k2.Ad_Id
AND k3.Keyword_Id =  (SELECT Id FROM keywords WHERE name = 'KEYWORD3')
AND k2.Ad_Id = k3.Ad_Id
AND k4.Keyword_Id =  (SELECT Id FROM keywords WHERE name = 'KEYWORD4')
AND k3.Ad_Id = k4.Ad_Id
AND k5.Keyword_Id =  (SELECT Id FROM keywords WHERE name = 'KEYWORD5')
AND k4.Ad_Id = k5.Ad_Id
4

3 に答える 3

1

これは、最初に見たときに思ったよりもかなりトリッキーだったので、おそらく考えすぎです。しかし、ここにあなたのために働くと私が信じている解決策があります:

var keywordList = new List<string>();
keywordList.Add("ALFA");
keywordList.Add("145");

var results = KeywordAdCategories.Select (kac => kac.Ad_Id).Distinct()
            .Select (a => 
                new
                { 
                    AdId=a,
                    Keywords=KeywordAdCategories.Where(kac => kac.Ad_Id == a).Select(kac => kac.Keyword_Id)
                })
            .Where(ac => ac.Keywords.Intersect(Keywords.Where(kw => keywordList.Contains(kw.Name)).Select (kw => kw.Id)).Count() == keywordList.Count())
            .Select (ac => ac.AdId);

ここで私が何をしたかを説明します。最初に、考えられるすべての広告 ID から始めたいので、次の行を作成します。

KeywordAdCategories.Select (kac => kac.Ad_Id).Distinct()

もちろん、これはおそらく広告テーブルからの個別の選択からより簡単に取得できますが、定義したものだけで作業しようとしています.

次に、関連するキーワードのコレクションを含む各広告 ID を選択して、型指定された匿名オブジェクトのリストに入れます。

.Select (a => 
              new
              { 
                  AdId=a,
                  Keywords=KeywordAdCategories.Where(kac => kac.Ad_Id == a).Select(kac => kac.Keyword_Id)
              })

次に、キーワード リストと交差し、キーワード リストと同じ数の結果要素を持つ Keywords のコレクションを含むオブジェクトのみに結果をフィルター処理します。

.Where(ac => ac.Keywords.Intersect(Keywords.Where(kw => keywordList.Contains(kw.Name)).Select (kw => kw.Id)).Count() == keywordList.Count())

最後に、その結​​果の広告 ID だけを選択します

.Select (ac => ac.AdId);

あなたが興味を持っているなら、ここにエミットされたSQLがあります

-- Region Parameters
DECLARE @p0 NVarChar(1000) = 'ALFA'
DECLARE @p1 NVarChar(1000) = '145'
DECLARE @p2 Int = 2
-- EndRegion
SELECT [t1].[Ad_Id]
FROM (
    SELECT DISTINCT [t0].[Ad_Id]
    FROM [KeywordAdCategories] AS [t0]
    ) AS [t1]
WHERE ((
    SELECT COUNT(*)
    FROM (
        SELECT DISTINCT [t2].[Keyword_Id]
        FROM [KeywordAdCategories] AS [t2]
        WHERE (EXISTS(
            SELECT NULL AS [EMPTY]
            FROM [Keywords] AS [t3]
            WHERE ([t2].[Keyword_Id] = [t3].[Id]) AND ([t3].[Name] IN (@p0, @p1))
            )) AND ([t2].[Ad_Id] = [t1].[Ad_Id])
        ) AS [t4]
    )) = @p2

あなたがやりたいことを達成するためのはるかにエレガントな方法があると確信していますが、単一の linq クエリですべてを実現できるかどうかを確認したかったのです。お役に立てれば。

于 2013-02-06T22:25:42.267 に答える
0
List<string> keywordnames = new List<string>();
// populate keywordsnames list    

IQueryable<int> AdIds = from k in KeywordAdCategories
    where 
        (from kw in Keywords where keywordnames.Contains(kw.name) select kw.id)
        .Contains(k.keyword_id)
    select k.Ad_Id;

また

List<string> keywordnames = new List<string>();
// populate keywordsnames list   

List<int> keywordnameids = (from kw in ctx.Keywords
                            where keywordnames.Contains(kw.name)
                            select kw.id).ToList();

List<int> AdIds = (from k in ctx.KeywordAdCategories
                   where keywordnameids.Contains(k.Keyword_Id)
                   select k.Ad_Id).ToList();
于 2013-02-06T19:18:38.337 に答える
-1
public static int GetAdId(string KeywordId)
{
    var dbContext = new MyDbContext();

    var result = (from k in in dbContext.KeywordAdCategories
                   where k.Keyword_Id == KeywordId
                   select k.Ad_Id).SingleOrDefault();

    return result;
}

このメソッドですべてのキーワード ID を実行すると、対応する広告 ID が取得されます。LINQ を読むことをお勧めします。慣れれば素晴らしいツールで、最初は少し怖く感じるかもしれませんが、習得するのはそれほど難しくありません。Pluralsight.com には、簡単に把握して学習できる素晴らしいビデオがたくさんあります :)

于 2013-02-06T19:13:15.297 に答える