1

シナリオ:

  • モジュール 1 にはタグ AB があります
  • モジュール 2 にはタグ AB があります
  • モジュール 3 にはタグ A があります
  • モジュール 4 にはタグ B があります
  • モジュール 5 にはタグ ABC があります

表内:

ModuleId TagId
1         A
1         B
2         A
2         B
3         A
4         B
5         A
5         B
5         C

調子:

  • TagId ex のリストがあります: List<> tagList = { A, B }
  • TagIds のリスト (つまり、tagList) 以外のすべての TagIds が同じ ModuleId に分類されるようにします。その結果、TagId C が返されます。

TSQL ステートメント -

select TagId 
from Table
where ModuleId in (
     select ModuleId 
     from Table
     where TagId in(A,B)
     group by ModuleId having count(ModuleId) = 2 )
and TagId not in (A,B)

LINQ ステートメント -

List<int?> temp = (from t1 in context.Table
                            where tagList.Contains(t1.TagId)
                            group t1 by t1.ModuleId into grouped
                            where grouped.Count() == tagList.Count()
                            select grouped.Key).ToList();

           var result = (from t2 in context.Table
                    where temp.Contains(t2.ModuleId) && !tagList.Contains(t2.TagId)
                    select t2).Distinct().ToList();

だから私の質問は-

  • このシナリオの最適なアプローチは何ですか?
  • より良いアプローチがあれば、それに対する LINQ メソッドの構文は何でしょうか?

前もって感謝します。

4

1 に答える 1

0

これは要件をより単純に翻訳したものですが、tagList が大きくなるにつれて、はるかに複雑になる SQL が生成されます。

// Get items from the table
from t in context.Table
// ... that belong to modules
group t by t.ModuleId into moduleTags
// ... that have items for all the tags in the tagList
where tagList.All(tagId => moduleTags.Any(t => t.TagId == tagId))
from t in moduleTags
// ... but which themselves don't have the same tags as in the tagList.
where !tagList.Contains(t.TagId)
select t;

それから始めて、「Count == Count」トリックを活用して、より適切にスケーリングする必要があるかなり単純な実装を次に示します。

// Get items from the table
from t in context.Table
// ... that belong to modules
group t by t.ModuleId into moduleTags
// ... that have items for all the tags in the tagList
where moduleTags.Count(t => tagList.Contains(t.TagId)) == tagList.Count()
from t in moduleTags
// ... but which themselves don't have the same tags as in the tagList.
where !tagList.Contains(t.TagId)
select t;

この後者の実装は、元の SQL と同様に、テーブル エントリと tagList の両方に個別のエントリのみがあることを前提としています。そうしないと、カウントがオフになります。

于 2013-11-01T21:43:24.220 に答える