问题
I am using .Take() to get a fixed number of results.
What is the best way to get the TotalCountBeforeTake
(ie as if I didn't use the .Take())?
Can I get the TotalCountBeforeTake
without running the query twice?
var Results = (from results in db.FindWords(term)
orderby results.word
select results.word).Take(100);
//just to get the total record count
int TotalCountBeforeTake = (from results in db.FindWords(term)
select results.word).Count();
// only showing 100 out of TotalCountBeforeTake results,
// but in order to know the TotalCountBeforeTake I had to run the query twice.
foreach (var result in Results)
{
Console.Write(result.ToString());
}
回答1:
You want to query two things - the total number of items and a subset of items. So you need to run two queries:
// Define queries
var query1 = from results in db.FindWords(term)
orderby results.word
select results.word;
var query2 = query1.Take(100);
// Run queries
int totalCountBeforeTake = query1.Count();
foreach (var result in query2)
{
Console.Write(result.ToString());
}
回答2:
I don't know of a way to get the count without splitting this up (hopefully someone else does) but in your situation I'd suggest:
//first get the records
var query = (from results in db.FindWords(term)
orderby results.word
select results.word).ToList();
//get the total record count
int TotalCountBeforeTake = query.Count();
// only showing 100 out of results,
foreach (var result in query.Take(100))
{
Console.Write(result.ToString());
}
回答3:
IEnumerables and LINQ are used to create a selection chain. Before you actually start iterating, nothing is being executed (except for creating the selection chain).
This seems magic, as it drastically boosts performance, because trying to achieve the same with lists requires several iterations over the list(s).
But when you start iterating over an enumerable more than once, you are buying the elegance of LINQ with multiple operations which drops your performance benefit to zero and below.
In other words: convert your linq expression into an array and continue.
var Results = (from results in db.FindWords(term)
orderby results.word
select results.word).Take(100).ToArray();
Now you can count, iterate without performance loss.
来源:https://stackoverflow.com/questions/18416873/how-to-get-total-results-count-before-take-but-when-using-take