按时间顺序获取最后x个条目的最佳方式

时间:2010-01-22 00:34:46

标签: c# lambda

我正在尝试按时间顺序获取最新的x条目。 目前我在做:

var query = db.OrderByDecending(x => x.date).Take(x).OrderBy(x => x.date)

从一个方向排序,限制然后在另一个方向排序似乎很疯狂。它不像我现在使用的那样导致我不眠之夜,我只是想知道是否有更好的方法......

3 个答案:

答案 0 :(得分:4)

通过第二次OrderBy调用,列表已经排序,但顺序错误。因此,您可以拨打Reverse,这会更快。

var query = db.OrderByDescending(x => x.date).Take(x).Reverse();

答案 1 :(得分:0)

这取决于'db'实际上是什么。如果它是一个集合,那么SLaks的建议。另一方面,ff是一个SQL数据库,这是一个linq2sql查询或linq到EF然后实际上两个OrderBy更好。这就是SQL的全部内容:描述所需的结果,让数据库引擎找出最佳的访问路径和查询计划以满足您的请求。

答案 2 :(得分:0)

它需要某种流缓冲区数据结构,但您可以非常轻松地编写TakeEnd方法。虽然在这种特殊情况下使用Reverse可能是一个更好的主意。

这可以让你做这样的事情:

var query = db.OrderBy(x => x.date).TakeEnd(x);

使用此代码:

public static class Ext
{
    private class StreamBuffer<T> : IEnumerable<T>
    {
        private int head = 0;
        private bool filled = false;

        private T[] stream;
        public int Size { get; private set; }

        public StreamBuffer(int size)
        {
            Size = size;
            stream = new T[Size];
        }

        public void Add(T item)
        {
            stream[head] = item;

            head += 1;
            if (head >= Size)
            {
                head = 0;
                filled = true;
            }
        }

        public IEnumerator<T> GetEnumerator()
        {
            int start = filled ? head : 0;
            int size = filled ? Size : head;
            for (int i = 0; i < size; i += 1)
            {
                int p = (start + i) % Size;
                yield return stream[p];
            }
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }

    public static IEnumerable<T> TakeEnd<T>(this IEnumerable<T> enumerable, int count)
    {
        StreamBuffer<T> buffer = new StreamBuffer<T>(count);
        foreach (T t in enumerable)
        {
            buffer.Add(t);
        }
        return buffer;
    }
}