开发者

Get count of an IQueryable<T>

Assume we have the following collection

 IEnumerable<int> list = new List<int> { 11, 12, 13, 14, 15, 16, 17, 18, 19, 10 };
 var query = list.Skip(5).Take(4);
 SomeMethod(query.AsQueryable()); 
 .
 .
 .
 public void SomeMethod(IQueryable<T> query)
 {
      var collectionCount = ?????  // count should be 10 not 4.
      ...
 }

How can I get the count of the original collection (without applying Skip and Take sub-queries) of the query in the SomeMethod.

T开发者_如何学Pythonhanks.


There is no way you could get the information (except maybe by doing some hardcore reflection stuff). It is simply not there anymore. It’s like you wanted to extract the original count from something like this:

var list = new List<int> { 11, 12, 13, 14, 15, 16, 17, 18, 19, 10 };
SomeMethod(list[3]);

public void SomeMethod(int number)
{
  var collectionCount = ?????  // count should be 10
  ...
}

I think you might be able to get the information if instead of IQueryable, you would pass Expression, however, even this case would not be simple.

Added per comments:

It is not as simple as you might think; I don’t even think it is possible fully generally. However, for some limited use cases it might work. I have quickly hacked a method which “removes” any Skip a Take applied to the query and returns the original count. Give it a try, YMMV:

public int CountOriginal<T>(IQueryable<T> query)
{
    var ex = query.Expression;
    while (ex.NodeType == ExpressionType.Call)
    {
        var call = (MethodCallExpression)ex;

        if (call.Method.Name != "Skip" && call.Method.Name != "Take") break;

        ex = call.Arguments[0];
    }
    var enumerable = Expression.Lambda(ex).Compile().DynamicInvoke(null) as IEnumerable<T>;
    if (enumerable == null) throw new NotImplementedException();
    return enumerable.Count();
}


list.Count should return the count of the original list

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜