获取IQueryable <t> </t>的计数

时间:2011-02-15 10:01:59

标签: c#-4.0 iqueryable

假设我们有以下集合

 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.
      ...
 }

如何在SomeMethod中获取查询的原始集合的计数(不应用Skip和Take子查询)。

感谢。

2 个答案:

答案 0 :(得分:0)

list.Count应该返回原始列表的计数

答案 1 :(得分:0)

你无法获得信息(除非做一些硬核反射的东西)。它根本就不存在了。这就像你想从这样的东西中提取原始数:

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
  ...
}

我认为你可能能够获取信息而不是IQueryable,你会通过Expression,但是,即使这种情况也不会很简单。

每次评论

添加

这并不像你想象的那么简单;我甚至认为完全普遍是不可能的。但是,对于某些有限的用例,可能工作。我很快就破解了一个方法,该方法“删除”应用于查询的任何Skip Take并返回原始计数。试一试,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();
}