IQueryableクエリの一部を実行するとオブジェクトのためのLINQに休息を延期

StackOverflow https://stackoverflow.com/questions/695678

質問

私はsucessfullyになり、私の選択したデータソースからデータを取得するのLINQプロバイダを持っていますが、私は今、私は私のフィルタ処理結果セットを持っていることをやりたいものを、もののために(オブジェクトへのLINQの式ツリーの残りの部分を処理することが可能です結合、投影など)

のような

私の考えは、私はちょうどExpressionVisitorを経由してIEnumerableを結果セットと私のIQueryProviderを含む発現定数を交換し、その新しい表現を返すということでした。また、私のIQueryableからのIEnumerableのプロバイダを返す...しかし、これは動作していないよう: - (

任意のアイデアの?

編集: ここではいくつかの良い答えが、しかし、フォームを与えられた...

var qry = from c in MyProv.Table<Customer>()
          Join o in MyProv.Table<Order>() on c.OrderID equals o.ID
          select new 
          {
            CustID = c.ID,
            OrderID = o.ID
          }
データは、私はちょうど構築し、結合構文をSQLに渡すSQLソースからだった場合は、

私のプロバイダでは、私は簡単に、顧客と注文から2つのResultSetを取り戻すことができますが、それはこの場合、データがSQLからではありませんそれだけで代用する本当のいいだろうソースので、私はコードに参加行う必要があります...しかし、私が言ったように、私は2つの結果セットを持っている、とLINQのオブジェクトへの参加行うことができます...(以降投影)式の定数は、ということが可能です... MyProv.Table<Customer>MyProv.Table<Order> List<Customer>List<Order>持つとList<>プロバイダプロセスに表現してみましょうか?どのように?

役に立ちましたか?

解決 2

私は後のコンクリート(.AsQueryable経由またはのIQueryable())IEnumerableを結果セットで式ツリーに一定の照会可能<>を置き換えしたもののようなものが...これはおそらく唯一のいずれかを作る複雑なトピックです式ツリーの来場者に深い膝いるのLINQプロバイダのライターへの感覚など。

私は後にしています何のような何かをするのMSDNのチュートリアルのスニペットを見つけ、これが私の進むべき道を与える...

using System;
using System.Linq;
using System.Linq.Expressions;

namespace LinqToTerraServerProvider
{
    internal class ExpressionTreeModifier : ExpressionVisitor
    {
        private IQueryable<Place> queryablePlaces;

        internal ExpressionTreeModifier(IQueryable<Place> places)
        {
            this.queryablePlaces = places;
        }

        internal Expression CopyAndModify(Expression expression)
        {
            return this.Visit(expression);
        }

        protected override Expression VisitConstant(ConstantExpression c)
        {
            // Replace the constant QueryableTerraServerData arg with the queryable Place collection.
            if (c.Type == typeof(QueryableTerraServerData<Place>))
                return Expression.Constant(this.queryablePlaces);
            else
                return c;
        }
    }
}

他のヒント

前の回答の両方が動作し、それはあなたがAsEnumerableを使用している場合()のIEnumerableへのIQueryableをキャストするために、より良い読みます:

// Using Bob's code...
var result = datacontext.Table
   .Where(x => x.Prop == val)
   .OrderBy(x => x.Prop2)
   .AsEnumerable()  //  <---- anything after this is done by LINQ to Objects
   .Select(x => new { CoolProperty = x.Prop, OtherProperty = x.Prop2 });

EDITます:

// ... or MichaelGG's
var res = dc.Foos
           .Where(x => x.Bla > 0)  // uses IQueryable provider
           .AsEnumerable()
           .Where(y => y.Snag > 0); // IEnumerable, uses LINQ to Objects

あなたがリポジトリパターンを実装した場合、あなただけ離れて背中と抽象テーブルをのIQueryableを提供して逃げることができます。

例:

var qry = from c in MyProv.Repository<Customer>()
          Join o in MyProv.Repository<Order>() on c.OrderID equals o.ID
          select new 
          {
            CustID = c.ID,
            OrderID = o.ID
          }

、その後、ちょうどちょうど<のhref = "http://iridescence.no/post/Linq-to-Sql-Programming-Against-an-Interface-andのようなあなたのリポジトリ方法でのIQueryableパターンをモデル化するために、プロバイダを構築-theリポジトリ-Pattern.aspx」REL = "nofollowをnoreferrer">この記事を示します。

このように、あなたは何が必要に使用するプロバイダのすべての種類を書くことができます。あなたは、LINQ 2 SQLプロバイダを持っている、またはあなたのユニットテストのためのメモリ・プロバイダーに書くことができます。

LINQ 2 SQLプロバイダのリポジトリ方法は、次のようになります:

public IQueryable<T> Repository<T>() where T : class
{
    ITable table = _context.GetTable(typeof(T));
    return table.Cast<T>();
}
私は誤解だ場合を除き、

、私は一般的にちょうど私がLINQプロバイダが実行する時点では、LINQメソッドのチェーンで.ToArray()を追加します。

例えば(LINQ to SQLは思う)。

var result = datacontext.Table
   .Where(x => x.Prop == val)
   .OrderBy(x => x.Prop2)
   .ToArray()
   .Select(x => new {CoolProperty = x.Prop, OtherProperty = x.Prop2});

だから、のOrderBy()はSQLに変換が、選択は()オブジェクトへのLINQで取得してます。

ロブの答えは良いですが、完全な列挙を強制します。あなたは、拡張メソッドの構文と遅延評価を維持するためにキャストすることができます:

var res = ((IEnumerable<Foo>)dc.Foos
            .Where(x => x.Bla > 0))  // IQueryable
          .Where(y => y.Snag > 0)   // IEnumerable
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top