请考虑以下事项:
T[] itemArray = // initialized values
IQueryable<T> itemQuery = itemArray.AsQueryable().Where(*/some query*/).Skip(5).Etc() ...
是否可以从itemArray
获取基础集合或数据集(在本例中为itemQuery
)?在我看来,如果在评估查询表达式时,必须针对原始集合对其进行评估,因此该集合必须存储在IQueryable中或由IQueryable引用。
如何做到这一点?
注意:
这是一个包含MongoDB linq驱动程序(来自10gen)的大型项目的一部分,我们正在尝试从基于mongo集合的IQueryable中提取原始MongoCollection。虽然我们使用的是IQueryable&lt;&gt;特别是对于MongoDB,这个问题的答案应该是IQueryable&lt;&gt;所固有的。因此独立于MongoDB驱动程序。
答案 0 :(得分:3)
IQueryable
很可能确实有对底层集合的引用(可能通过多个间接层),但它不会公开暴露,因此您将无法访问它,至少不会以任何方式考虑合理而不是非常非常混乱的黑客。
答案 1 :(得分:0)
不,每个查询都是独立执行的,而您剩下的只是查询本身的结果集。内存对象中没有任何内容包含原始集合,也没有任何对原始集合的可访问引用。考虑到原始集合现在可能为空或超出范围,这甚至是允许的。如果您需要原始集合,则需要将其保留在范围内,直到完成它为止。
答案 2 :(得分: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;