エンティティへのLINQに条件付き含める?

conditional entity-framework include linq

質問

次のようなことが可能であるべきだと私は感じました。

私がやりたいことは、私の結果を形作るためにincludeメソッドを使うことです。すなわち、オブジェクトグラフに沿ってどれだけトラバースするかを定義します。しかし...私はその走査が条件付きであることを望みます。

something like...

dealerships
    .include( d => d.parts.where(p => p.price < 100.00))
    .include( d => d.parts.suppliers.where(s => s.country == "brazil"));

これは有効なlinqではないこと、実際にはそれはひどく間違っていることを理解していますが、本質的には整形式の結果を返す式ツリーを構築する方法を探しています

select *
from dealerships as d
outer join parts as p on d.dealerid = p.dealerid
    and p.price < 100.00
outer join suppliers as s on p.partid = s.partid
    and s.country = 'brazil'

結合条件に重点を置いて。

私はこれがesqlでかなり簡単であるように感じるが 、私の好みはその場で表現木を作ることであろう。

いつものように、どんなアドバイスやガイダンスにも感謝します

受け入れられた回答

これでうまくいくはずです。

using (TestEntities db = new TestEntities())
{
    var query = from d in db.Dealership
                select new
                {
                    Dealer = d,
                    Parts = d.Part.Where
                    (
                        p => p.Price < 100.0 
                             && p.Supplier.Country == "Brazil"
                    ),
                    Suppliers = d.Part.Select(p => p.Supplier)
                };

    var dealers = query.ToArray().Select(o => o.Dealer);
    foreach (var dealer in dealers)
    {
        Console.WriteLine(dealer.Name);
        foreach (var part in dealer.Part)
        {
            Console.WriteLine("  " + part.PartId + ", " + part.Price);
            Console.WriteLine
                (
                "  " 
                + part.Supplier.Name 
                + ", " 
                + part.Supplier.Country
                );
        }
    }
}

このコードはあなたにディーラーシップのリストを与えるでしょう、各々は部品のフィルターにかけられたリストを含みます。各パートはサプライヤを参照しています。興味深いのは、表示されている方法でselectで匿名型を作成する必要があるということです。それ以外の場合、DealershipオブジェクトのPartプロパティは空になります。

また、クエリからディーラーを選択する前にSQLステートメントを実行する必要があります。それ以外の場合、ディーラーのPartプロパティは再び空になります。それで、ToArray()呼び出しを次の行に入れます。

var dealers = query.ToArray().Select(o => o.Dealer);

しかし、これはあなたのライブラリのユーザが期待しているものではないかもしれないということで私はDarrenに同意します。


人気のある回答

これがあなたが望むものであると確信していますか?私が尋ねる唯一の理由は、一旦あなたがディーラー外の部品にフィルタを追加すると、あなたの結果はもはやディーラーではないということです。あなたは、(大体において、(同じ特性を持つ)ディーラーシップに非常に近い)特別なオブジェクトを扱っていますが、 "Parts"プロパティの意味は異なります。ディーラーと部品の間の関係ではなく、フィルターされた関係です。

言い換えれば、私があなたの結果からディーラーを引き抜いて、私が書いたメソッドに渡したなら、私のメソッドの中で私はこう呼びます:

var count = dealership.Parts.Count();

私は価格が100ドル以下であるブラジルからのフィルターをかけられた部品ではなく部品を手に入れることを期待しています。

フィルタリングされたデータを渡すためにディーラーオブジェクトを使用しなければ、それは非常に簡単になります。それはと同じくらい簡単になります:

    var query = from d in dealerships
               select new { DealershipName = d.Name, 
CheapBrazilProducts = dealership.Parts.Where(d => d.parts.Any(p => p.price < 100.00) || d.parts.suppliers.Any(s => s.country == "brazil")) };

私があなたが求めたようにフィルターセットを取得しなければならなかったなら、私はおそらく私が上で述べたテクニックを使い、それから私の匿名クラスから実際のクラスにフィルター結果をコピーするためにAutomapperのようなツールを使います。信じられないほど洗練されているわけではありませんが、うまくいくはずです。

私はそれが役立つことを願っています!おもしろい問題でした。



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ