以LINQ方式返回最大数量的项目

时间:2013-07-02 19:26:40

标签: c# linq

假设我有一个带有底层数据存储库的搜索模块,并且要求从搜索查询中返回最多25个结果。我可以使用Take()操作强制执行此操作:

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

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

接下来,假设如果返回的结果超过25个(即搜索参数太宽),我还需要抛出异常。使用LINQ有一种直接的方法吗?到目前为止,我最接近的是取一个多于最大数量并使用它:

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;
}

然而,这似乎有点笨拙。

2 个答案:

答案 0 :(得分:9)

您的方法是最好的方法。我根本不会做任何改变。

任何其他选项,例如首先单独查询计数,如果您的项目少于26项,则执行看似昂贵的操作(进行实际搜索)两次。在错误情况下只保留一点点,并在常见情况下增加了大量费用。

唯一一次你的代码不那么令人满意的是,如果_repository.Search(name)返回的类型可以廉价地迭代两次并且可以便宜地提供它的计数(比如说,List)但是在上下文中似乎并非如此。

答案 1 :(得分: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;
        }
    }
}