以LINQ方式返回最大项目数

本文关键字:项目数 返回 LINQ 方式 | 更新日期: 2023-09-27 18:20:42

假设我有一个带有底层数据存储库的搜索模块,并且要求从搜索查询中最多返回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;
}

然而,这似乎有点笨拙。

以LINQ方式返回最大项目数

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

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

如果_repository.Search(name)返回了一个类型,该类型可以廉价地迭代两次,并且可以廉价地提供它的计数(比如List),但在上下文中,情况似乎并非如此。

您可以制作自己的通用迭代器块扩展方法,并将其用于任何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;
        }
    }
}