2016-10-07 8 views
0

エンティティフレームワークで解決しようとしている関係分割の問題があります。エンティティフレームワークリレーショナル部門の実装

私は2つのテーブルを持っています。ものともの。 それぞれのスタッフは多くのものを持つことができます。

私が扱う必要がある唯一のDbSetは、ThingIdと関連StuffIdを含むStuffとThingの正規化ビューです。

私は一連の条件でThingsビューを照会しており、関連するStuffのすべてのThingsが結果セットに存在するものを選択する必要があります。私。場所条件が適用された後に物事が欠落している場合は、その物事に関連する物をすべて削除します。

私は動作すると思われるクエリとして生成しましたが、実行速度が遅すぎ、一般にSQLタイムアウトに遭遇します。私はそれがすぐに実行する必要があります。ここで

は私の例です:

public IQueryable<Thing> GetCompleteThingsWhere 
            (Expression<Func<BetSelection, bool>> conditions) 
{ 
    var filteredThings = this._dbContext.GetQuery<Thing>().Where(conditions); 

    var allThings = this._dbContext.GetQuery<Thing>(); 

    var allThingsForFilteredThings = 
     allThings.Where(x => filteredThings.Any(y => y.StuffId == x.StuffId)); 

    var missingThingsFromFilteredThings = 
     allThingsForFilteredThings.Where(x => filteredThings 
               .All(y => y.ThingId != x.ThingId)); 

    var completeStuffThings = 
     filteredThings.Where(x => !missingThingsFromFilteredThings 
            .Any(y => x.StuffId == y.StuffId)); 

    return completeStuffThings; 
} 

クエリの実行には約6分を取っているし、SQLはWHERE句のサブクエリに元の状態を実行して、非常に非効率的に見えます。

さらなる説明:

Results 
____________________ 
| ThingId | StuffId | 
|1  |1  | 
|4  |2  | 
|5  |2  | 
|6  |2  | 
:スタッフと物事

サンプル・データ

STUFF   THING 
__________  ____________________ 
| StuffId |  | ThingId | StuffId | 
|1  |  |1  |1  | 
|2  |  |2  |1  | 
|   |  |3  |1  | 
|   |  |4  |2  | 
|   |  |5  |2  | 
|   |  |6  |2  | 

私たちは私たちの結果が設定されているように、条件パラメータは、物事のセットをフィルタリングするとしましょう

StuffId 1に関連するものの2つが結果セットに存在しないので、今度はSのすべてのものを削除したい私は条件クエリが最初に実行されるように、小さなクエリにアップクエリを破壊することにより、第2の下に6分からのクエリの実行時間を短縮するために管理し、唯一の完全なスタッフ

Results 
____________________ 
| ThingId | StuffId | 
|4  |2  | 
|5  |2  | 
|6  |2  | 
+0

?理解することは本当に難しいです。より正確な例を挙げられますか?この行のプリプロスは何ですか?var allThingsForFilteredThings = allThings.Where(x => filteredThings.Any(y => y.StuffId == x.StuffId)); '?それはあなたにすべてのろ過されたものを与えませんか? –

+0

テーブルにこれらのクエリの正しいインデックスがありますか? – mxmissile

+0

@mxmissileはい彼らは –

答えて

0

残して結果セットからtuffId 1、 EFがサブクエリを生成するのではなく、リレーショナル部門を実行するときに使用する一連のIDを提供します。

0

私があなたを理解していれば、あなたはすべてのものがすべての状態に合っているスタッフに属していますか?

public IQueryable<Thing> GetCompleteThingsWhere 
           (Expression<Func<BetSelection, bool>> conditions) 
{ 
    return this._dbContext.GetQuery<Stuff>().Where(e => e.Things.All(conditions)) 
              .Select(e => e.Things); 
} 

正規化StuffThing(コメントを参照)での作業の場合:正確に何をしようとする

public IQueryable<Thing> GetCompleteThingsWhere 
           (Expression<Func<BetSelection, bool>> conditions) 
{ 
    return this._dbContext.GetQuery<StuffThing>() 
          .GroupBy(e => e.StuffId) // Denormalize 
          .Where(g => g.All(conditions)) 
          .SelectMany(g => g); 
} 
+0

あなたの答えを読んだ後、私はちょうど私がそれを正しく説明していないことに気づいた。テーブルThingとStuffがありますが、私が照会しなければならない唯一のEFモデルクラスは、2つのエンティティからのデータを結合する正規化ビューです。もし私が非正規化モデルを使っていたらあなたの答えは意味をなさないでしょう。ありがとう! –

+0

@GlenThomas物事をより明確にするために、あなたは「StuffThing」エンティティを持っています。 – Vlad274

+0

それはおそらく動作するように見えます!私は月曜日にそれをテストします –