Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从IQueryable获取原始收藏<;T>;_C#_Linq_Iqueryable - Fatal编程技术网

C# 如何从IQueryable获取原始收藏<;T>;

C# 如何从IQueryable获取原始收藏<;T>;,c#,linq,iqueryable,C#,Linq,Iqueryable,考虑以下几点: T[] itemArray = // initialized values IQueryable<T> itemQuery = itemArray.AsQueryable().Where(*/some query*/).Skip(5).Etc() ... T[]itemArray=//初始化值 IQueryable itemQuery=itemArray.AsQueryable()。其中(*/some query*/)。跳过(5).Etc()。。。 是否可以从it

考虑以下几点:

T[] itemArray = // initialized values
IQueryable<T> itemQuery = itemArray.AsQueryable().Where(*/some query*/).Skip(5).Etc() ...
T[]itemArray=//初始化值
IQueryable itemQuery=itemArray.AsQueryable()。其中(*/some query*/)。跳过(5).Etc()。。。
是否可以从
itemQuery
获取基础集合或数据集(在本例中为
itemrarray
)?在我看来,如果在计算查询表达式时,必须对原始集合进行计算,因此该集合必须存储在IQueryable中或由IQueryable引用

如何做到这一点

注:

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

IQueryable最有可能引用底层集合(可能通过若干层间接寻址),但是它不会公开暴露,所以你将无法访问它,至少在任何我认为合理的,而不是一个非常非常凌乱的黑客的情况下。

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

这是一种欺骗,但在您的上下文中可能有意义:

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
}
当您需要源代码序列时,您可以通过
source
成员访问它,也可以通过
as
cast访问它

var s = itemQuery.Source;

+1-我相信EF Linq提供程序只存储任何过滤器等,以便投影SQL,因此可能无法使用
IQueryable
引用访问整个表。我希望MongoDB提供程序与之类似,不会过滤内存中的数据。好吧,原始集合必须存在于某个地方。这里的查询使用的是延迟执行,所以它只是定义如何从集合中提取数据,直到您尝试枚举它,它才真正提取数据。因此,它需要有一个对实际收藏的引用(至少是间接引用)。@Servy:Yah,我用“可访问”这个词进行了编辑。出于执行目的,存在对原始集合的引用,但没有可访问的引用。我不是100%确定,但我相信一旦执行完毕,这个引用就会被丢弃。不过,不要引用我的话。在我看来,我在某个地方读到了这样的东西(或者至少是让我相信的东西:),虽然定制查询提供者确实可以做到这一点,但明智的人是不会做到的。对于初学者来说,您可以多次枚举[大多数]查询,因此故意丢弃枚举“您自己”所需的信息会阻止这一点(标准提供者都不会这样做)。正如我在回答中所说,您可能(实际上)无法从
IQueryable
中获取引用,但它就在那里(某个地方)。@Servy:一旦执行发生,新数据将加载到单独的内存空间中。原始引用只需要存在足够长的时间就可以执行。虽然现在你激起了我的好奇心。我将不得不运行一些范围测试,以查看当源集合在执行之后和之前超出范围时,延迟执行会发生什么情况。正如我所说,查询将在源集合的整个生命周期中保留对源集合的引用,因此,根据定义,在查询发生之前,源集合不能超出范围。引用实际集合(实际程序员有权访问)的某些变量可能超出范围,但在可查询项消失之前,基础集合(本例中为数组)不能超出范围。如果它这样做了(可能是通过表示不安全的代码),那么查询将中断,因为它将查询不再存在的数据。
var s = itemQuery.Source;