3

私はクエリを持っています:

var q = (
    from c in db.tblStoreRecommendations
    where
    itemIDsInCart.Contains(c.ItemID)
    && !itemIDsInCart.Contains(c.RecommendItemID)
    select c
);

次の行に沿って何かを返します。

ID    ItemID    RecommendItemID    Message
------------------------------------------
1     25        3                  Msg here
2     26        3                  Something else
3     27        8                  Another message

同じ を持つ結果を除外するクエリが必要ですRecommendItemID。これは、返された結果に複数回表示されるべきではありません。

2 つ存在する場合は、どちらでも使用できます (ランダムな選択が最適です)。したがって、返される結果では、レコード ID 1 または 2 が省略されます。

誰でもこれを行う方法を教えてもらえますか? ありがとう!

4

3 に答える 3

6

1つのアプローチは、GroupByを使用してから、各グループから最初のアイテムを選択することです。

var q = (
    from c in db.tblStoreRecommendations
    where
        itemIDsInCart.Contains(c.ItemID)
     && !itemIDsInCart.Contains(c.RecommendItemID)
    select c
).GroupBy(c => c.RecommendItemID)
 .Select(g => g.First());

Firstこれを使用してランダムなレビューを表示している場合は、次のように省略して、LINQクエリではなく使用コードにこれを追加することをお勧めします。

var q = (
    from c in db.tblStoreRecommendations
    where
        itemIDsInCart.Contains(c.ItemID)
     && !itemIDsInCart.Contains(c.RecommendItemID)
    select c
).GroupBy(c => c.RecommendItemID)
 .Select(g => g.ToArray());

var random = new Random();
foreach (var r in q)
{
    var rec = r[random.Next(r.Length)];
    // use your recommendation
}
于 2012-07-16T20:31:15.940 に答える
3

次のように、linq式の最後に明確な比較を追加できると思います。

var q = (
  from c in db.tblStoreRecommendations
  where
  itemIDsInCart.Contains(c.ItemID)
  && !itemIDsInCart.Contains(c.RecommendItemID)
  select c
)
.Distinct((x, y) => x.RecommendItemID == y.RecommendItemID);

編集

自分で作成した拡張メソッドを使用してこれを実行したことに気づきました。通常は便利です...コードは次のとおりです。

    /// <summary>
    /// Provides a way to get a distinct list of items based on a lambda comparison operator.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="source"></param>
    /// <param name="equalityComparer">A comparison function that returns true of the two items are considered equal.</param>
    /// <returns>The list of distinct items.</returns>
    public static IEnumerable<T> Distinct<T>(this IEnumerable<T> source, Func<T, T, bool> equalityComparer)
    {
        var distincts = new List<T>();
        foreach (var item in source)
        {
            var found = false;
            foreach (var d in distincts)
            {
                found = equalityComparer(item, d);
                if (found)
                    break;
            }

            if (!found)
            {
                distincts.Add(item);
                yield return item;
            }
        }
    }
于 2012-07-16T20:31:16.597 に答える
1

可能な限りクエリ式に固執してみましょう。

var q = from c in db.tblStoreRecommendations
        where itemIDsInCart.Contains(c.ItemID)
          && !itemIDsInCart.Contains(c.RecommendItemID)
        group c by c.RecommendItemID into matches
        select matches.First();

ここでは、コンテキスト キーワードintoが役立ちます。

ランダム化する方法は次のとおりです。

private static Random random = new Random();

var q = from c in db.tblStoreRecommendations
        where itemIDsInCart.Contains(c.ItemID)
          && !itemIDsInCart.Contains(c.RecommendItemID)
        group c by c.RecommendItemID
        into matches
        select matches.AsEnumerable().ElementAt(random.Next(matches.Count()));

LINQ to SQL は呼び出しを処理できないため、グループ化から Random 要素を選択する前に、ElementAt( を呼び出して) クエリを実行するように回答を編集しました。AsEnumerable

于 2012-07-16T20:48:16.243 に答える