0

私は、ユーザーが公開情報をキーワードに参加させることができるインターフェースを設計しています。参加する場合は、選択したキーワードと並行して一般的に発生する他のキーワードを提案したいと思います。秘訣は、提案されたキーワードのプロパティと一緒に相関の頻度を取得することです。

キーワードタイプ(EF)には、次のフィールドがあります。

int Id
string Text
string UrlString

...そしてPublicationsエンティティセットとの多対多の関係。
もうすぐです。と :

var overlappedKeywords =
            selectedKeyword.Publications.SelectMany(p => p.Keywords).ToList();

ここで、非常に便利なものが得られます。キーワードのフラット化されたリストです。それぞれがリストに複製されますが、selectedKeywordと並行して表示されることが何度もあります。

残りの課題:
したがって、各キーワードがこのリストに表示される回数をカウントし、Keywordと同じフィールドを持ち、フィールドが1つ追加されたKeywordCountsという新しいタイプに個別のint PublicationsCountキーワードエンティティを投影します。ここに、overlappedKeywords内の各キーワードの数を入力します。これどうやってするの??

これまでに2つのアプローチを試しました。

var keywordCounts = overlappingKeywords
    .Select(oc => new KeywordCount
        {
            KeywordId = oc.Id,
            Text = oc.Text,
            UrlString = oc.UrlString,
            PublicationsCount = overlappingKeywords.Count(ok2 => ok2.Id == oc.Id)
        })
    .Distinct();

... PublicationsCountは正しく入力されていますが、ここではDistinctが機能していません。(このためにEqualityComarerを作成する必要がありますか?デフォルトのEqualityComarerが機能しないのはなぜですか?)

var keywordCounts = overlappingKeywords
    .GroupBy(o => o.Id)
    .Select(c => new KeywordCount
        {
            Id = ???
            Text = ???
            UrlString = ???
            PublicationsCount = ???
        })

GroupByについてはよくわかりません。Selectの「o」にアクセスできないようです。cがKeywordのプロパティと競合していません。

更新
私の最初のアプローチは、.Distinct()に渡された単純なEqualityComparerで機能します。

class KeywordEqualityComparer : IEqualityComparer<KeywordCount>
{
    public bool Equals(KeywordCount k1, KeywordCount k2)
    {
        return k1.KeywordId== k2.KeywordId;
    }

    public int GetHashCode(KeywordCount k)
    {
        return k.KeywordId.GetHashCode();
    }
}

...しかし、Slaumaの答えは、これを必要としないため、望ましい(そして受け入れられる)。EFエンティティインスタンスのデフォルトのEqualityComparerがどうなるかについては、まだ困惑しています。上記のように、プライマリIDに基づいて比較するだけではないでしょうか。

4

1 に答える 1

1

2回目の試行は、より良いアプローチです。完全なコードは次のようになると思います。

var keywordCounts = overlappingKeywords
    .GroupBy(o => o.Id)
    .Select(c => new KeywordCount
    {
        Id = c.Key, 
        Text = c.Select(x => x.Text).FirstOrDefault(),
        UrlString = c.Select(x => x.UrlString).FirstOrDefault(),
        PublicationsCount = c.Count()
    })
    .ToList();

これはLINQtoObjectsだと思います。これは、EFコンテキストではなくオブジェクトが関係しているように見えるoverlappingKeywordsため、グループ化はデータベースではなくメモリで行われるためです。

于 2012-04-27T11:13:16.250 に答える