2

考虑以下:

T[] itemArray = // initialized values
IQueryable<T> itemQuery = itemArray.AsQueryable().Where(*/some query*/).Skip(5).Etc() ...

是否可以从中获取基础集合或数据集(在这种情况下itemArrayitemQuery?在我看来,如果在评估查询表达式时,必须根据原始集合对其进行评估,因此该集合必须存储在 IQueryable 中或由 IQueryable 引用。

如何才能做到这一点?

注意:
这是一个带有 MongoDB linq 驱动程序(来自 10gen)的更大项目的一部分,我们试图从基于 mongo 集合的 IQueryable 中提取原始 MongoCollection。尽管我们专门针对 MongoDB 使用 IQueryable<>,但这个问题的答案应该是 IQueryable<> 所固有的,因此独立于 MongoDB 驱动程序。

4

3 回答 3

3

IQueryable有可能确实引用了底层集合(可能通过多个间接层),但它不会公开,因此您将无法访问它,至少不能以我认为的任何方式访问它会认为是合理的,而不是非常非常混乱的黑客行为。

于 2012-10-03T19:58:24.293 回答
0

这是作弊,但也许在您的上下文中是有意义的:

interface IReferencedQueryable<T> : IQueryable<T>
{
    IEnumerable<T> Source { get; }
}

static class IReferencedQueryableExtensions
{
    public static IReferencedQueryable<T> AsReferencedQueryable<T>(
        this IEnumerable<T> source)
    {
        return ReferencedQueryable.From(source);
    }

    class ReferencedQueryable<T> : IReferencedQueryable<T>
    {
        public IEnumerable<T> Source { get; private set; }

        ReferencedQueryable(IEnumerable<T> source)
        {
            Source = source;
        }

        static IReferencedQueryable<T> From(IEnumerable<T> source)
        {
            return new ReferencedQueryable(source);
        }

        // all the IQueryable members would be 
        // implemented through AsQueryable()
        // ...
    }

    public static IReferencedQueryable<T> Where<T>(
        this IReferencedQueryable<T> source, 
        Expression<Func<T, bool>> predicate)
    {
        return ReferencedQueryable.From(
            ((IQueryable<T>)source).Where(predicate));
    }

    // do the same for all the Linq extension methos you want to support
}

你会像这样使用它:

T[] itemArray = // initialized values
var itemQuery = itemArray.AsReferencedQueryable()
                         .Where(*/some query*/)
                         .Skip(5)
                         .Etc() ...

当您需要您的源序列时,您可以通过Source成员访问它,可能通过as演员表。

var s = itemQuery.Source;
于 2012-10-12T14:52:46.230 回答
0

不,每个查询都是独立执行的,剩下的就是查询本身的结果集。内存对象中没有任何内容包含原始集合,也没有对原始集合的任何可访问引用。考虑到原始集合现在可能为空或超出范围,即使允许这样做也是危险的。如果您需要原始集合,则需要将其保留在范围内,直到您完全完成它为止。

于 2012-10-03T19:58:43.210 回答