2

次の点を考慮してください。

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

から基礎となるコレクションまたはデータセット (この場合itemArray)を取得することは可能itemQueryですか? クエリ式が評価される場合、元のコレクションに対して評価する必要があるため、そのコレクションを IQueryable に格納または参照する必要があるようです。

これはどのように行うことができますか?

注:
これは、mongo コレクションに基づく IQueryable から元の MongoCollection を抽出しようとしている、MongoDB linq ドライバー (10gen から) を使用したより大きなプロジェクトの一部です。特に MongoDB に関して IQueryable<> を使用していますが、この質問に対する答えは IQueryable<> に固有のものであるため、MongoDB ドライバーとは無関係です。

4

3 に答える 3

3

ほとんどのIQueryable場合、基になるコレクションへの参照があります (おそらく間接的なレイヤーを介して) が、公開されないため、少なくとも私が行った方法ではアクセスできません。合理的であり、非常に厄介なハックではないと考えられます。

于 2012-10-03T19:58:24.293 に答える
0

いいえ、各クエリは個別に実行され、クエリ自体の結果セットだけが残ります。元のコレクションや元のコレクションへのアクセス可能な参照を含むメモリ オブジェクト内には何もありません。元のコレクションが null または範囲外になる可能性があることを考えると、これを許可することさえ危険です。元のコレクションが必要な場合は、完全に終了するまでスコープ内に保持する必要があります。

于 2012-10-03T19:58:43.210 に答える
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 に答える