4

基盤となるデータ リポジトリを備えた検索モジュールがあり、検索クエリから最大 25 件の結果を返す必要があるとします。Take() 操作でこれを強制できます。

IEnumerable<Contact> Search(string name)
{
    // validation/cleanup on name parameter

    IEnumerable<Contact> matching = _repository.Search(name);
    return matching.Take(25);
}

次に、25 を超える結果が返される場合 (つまり、検索パラメーターが広すぎる場合) に例外をスローするという追加の要件があるとします。LINQ でこれを行う簡単な方法はありますか? これまでに最も近いのは、最大数よりも1つ多い数を取り、それを操作することです:

IEnumerable<Contact> Search(string name)
{
    // validation/cleanup on name parameter

    var matching = _repository.Search(name);
    var toReturn = matching.Take(26).ToList();
    if (toReturn.Count() > 25)
    {
        throw new Exception("Too many results");
    }

    return toReturn;
}

ただし、これは必要以上に扱いにくいようです。

4

2 に答える 2

9

あなたの方法は最良の方法です。私はまったく変更を加えません。

最初にカウントのみを照会するなどの他のオプションは、アイテムが 26 未満の場合、コストがかかると思われる操作 (実際の検索を行う) を 2 回実行することになります。エラーの場合はほんのわずかしか節約できず、一般的な場合にはかなりの費用がかかります。

コードがあまり望ましくない唯一の場合_repository.Search(name)は、安価に 2 回反復でき、安価にカウントを提供できる型 (たとえば、 a List) が返された場合ですが、コンテキストではそうではないようです。

于 2013-07-02T19:34:04.947 に答える
0

独自の汎用イテレータ ブロック拡張メソッドを作成して、任意の に使用できますIEnumerable<T>

public static class EnumerableExtensions
{
    public static IEnumerable<T> TakeWithMaximum<T>(this IEnumerable<T> source, int maxCount)
    {
        if (source == null)
            throw new ArgumentNullException("source");

        int count = 0;
        foreach (T item in source)
        {
            if (++count > maxCount)
                throw new InvalidOperationException(string.Format("More than the maximum specified number of elements ({0}) were returned.", maxCount));

            yield return item;
        }
    }
}
于 2013-07-02T19:53:33.977 に答える