Best way to Get Latest x entries, in chronological order
I'm trying to get the latest x entries开发者_开发问答 in chronological order. currently I'm doing:
var query = db.OrderByDecending(x => x.date).Take(x).OrderBy(x => x.date)
It seems crazy to be sorting in one direction, limiting and then sorting in the other. Its not like what I'm currently using is causing me sleepless nights, I just wonder whether there is a better way...
By the second OrderBy
call, the list is already sorted, but in the wrong order. Therefore, you can call Reverse
, which will be faster.
var query = db.OrderByDescending(x => x.date).Take(x).Reverse();
It depends what 'db' is actually. If its a a collection then SLaks advice stands. On the other hand ff is a SQL database and this is a linq2sql query or a linq to EF then actually the two OrderBy are better. that's what SQL is all about: describe the desired result and let the database engine figure out the optimal access path and query plan to satisfy your request.
It requires some sort of stream buffer data structure, but you can quite easily write a TakeEnd
method. Though in this specific case using Reverse is probably a better idea.
This would allow you to do something like this:
var query = db.OrderBy(x => x.date).TakeEnd(x);
using this code:
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;
}
}
精彩评论