2016-11-05 4 views
3

を存在する場合、私は、次の(一般)クエリを持っている:はEFクエリのパフォーマンスの改善 - チェック行がプリフェッチリストに<string>

var listOfPossibleCars= new List<string>(); 
var listOfCars = db.Cars.Where(s => listOfPossibleCars.Contains(s.CarName)).ToList(); 

しかしlistOfPossibleCarsは、任意のレコードの数十万人が含まれている大規模です。このクエリは遅延を引き起こしており、どのように改善できるのか不思議です。

+0

listOfPossibleCarsは常に同じですか、頻繁に(各呼び出しごとに)変更されていますか? – Evk

+0

@エヴァーク毎回違うよ、いつも大きいよ – SB2055

+0

車のテーブル全体の大きさはどれくらいですか?それを記憶に持っていくことは実現可能でしょうか?それ以外の場合は、SqlBulkIncertを使用してtempテーブルを作成し、@Evikのような結合を行うことをお勧めしますが、2つのテーブル、1つのクエリIDを持つことをお勧めします。 FilterID、varchar値)。したがって、各フィルタをロックする必要がなく、同時に誰もそれを更新しようとしないようにすることができます –

答えて

2

メモリ内のコレクションでこれを行うのではなく、listOfPossibleCarsのデータを適切に定義されたインデックスとパーティションを持つテンポラリテーブルに挿入し、これをデータベースに挿入します。適切に定義されたテーブルを使用すると、データベースはハッシュ結合を実行します。

データがデータベースになった後、クエリは次のようになります。listOfPossibleCarsは(すべてで、または多くの場合ではない、少なくとも変更されません)比較的静的な場合は説明するように、あなたが実際にデータベースにそれを置くことができる

//Instead data to database 
from car in db.Cars 
join possibleCar in db.PossibleCars on car.CarName equals possibleCar.CarName 
select car; 
+0

問題は、EFでこれらのエンティティの変更を追跡する必要があるということです... EFクエリでこれをどのように達成できるか考えてみてください。 – SB2055

+0

リストをデータベースに挿入するだけで、DBがより効率的なフィルタリングを行うことができます。後で 'cars'を使ってやってみたいことは、後ででも行うことができます –

+1

OPは、オブジェクトへのLINQではなくエンティティフレームワーククエリを作成するので、List to HashSetを変更しても効果はありません。 – Evk

2

別の答えで。そうでない場合や、SQL Serverを使用していると仮定した場合は、テーブル値のパラメータを使用できます。 Entity FrameworkはContains、特に長いリストでは非常に遅いことに注意してください。

まず、データベース内のカスタム・テーブル・タイプを作成します(何かがうまくいかない場合は、これはテストされたコードが私の頭から右ではないことに注意してください、そう尋ねる)

CREATE TYPE MyType AS TABLE 
(
    CarName varchar(200) primary key  
) 

は次に、このようなクエリ:

var listOfPossibleCars = new List<string>(); 
var dt = new DataTable(); 
dt.Columns.Add("CarName"); 
foreach (var car in listOfPossibleCars) { 
    dt.Rows.Add(car); 
} 
var possibleCars = new SqlParameter("possibleCars", SqlDbType.Structured); 
possibleCars.Value = dt; 
possibleCars.TypeName = "dbo.MyType"; 

var listOfCars = db.Cars.SqlQuery("select C.* from Cars C inner join @possibleCars P on C.CarName = P.CarName", possibleCars).ToList(); 

はい、生のSQLクエリを使用する必要がありますが、リストが本当に巨大な場合は、Entity Frameworkだけで効率的にクエリを実行することはできません。

+0

SqlQueryを使用して検索すると、変更トラッキングが保持されますか? – SB2055

+0

Database.SqlQueryは、追跡されていないエンティティを返します。ただし、DbSet.SqlQueryを使用すると、追跡対象のエンティティ(つまり、db.Cars.SqlQuery)を返すことができます。私の更新された答えを見てください。 – Evk

+0

@MichalCiechanここに何も挿入していないのですが、どういうことですか? – Evk

関連する問題