私のアプリでちょっとしたことをしようとしています。私はテーブル、Advertsを持っています - 車に関する情報が含まれています:モデル、走行距離など。テーブルは外部キーを介して他のいくつかのテーブルに関連しています。モデル名は「VehicleModels」テーブルなどにリンクする外部キーを介して取得されます。大きいテーブルの.Skip()および.Take()の前に、エンティティフレームワーク4.1の.ToList()を呼び出す必要があります。
アプリの「Entities」ディレクトリ(データベースのテーブルにマップするクラス)内に、AdvertsテーブルのAdvert.csがあります。これには、EFがAdvertsテーブルの実際のフィールドにマップしないので、(流暢なAPIで)無視するように言われているプロパティがいくつかあります。
これらのフィールドの背後にあるアイデアは、ユーザが入力した郵便番号(郵便番号)から計算された距離を、特定の半径内で利用可能な車を見たい場合に広告テーブルをフィルタリングする検索フォームに格納することです。例えば:
IQueryable<Advert> FilteredAdverts = repository.Adverts
.Where(am => mfr == "" || am.Manufacturer == mfr) &&
(am => model == etc etc...)
はその後、距離を計算するためのコードは次のようになります。
if (userPostcode != null) {
foreach (var ap in FilteredAdverts.ToList()) {
distmiles = //calculate distance in miles
distkm = //calculate distance in km
ap.DistanceMiles = Convert.ToInt32(distmiles);
ap.DistanceKm = Convert.ToInt32(distkm);
}
}
私がいる問題は、これらの二つのフィールドに値を割り当てるために、私が抱えているということですテーブルからすべての行を引っ張っている.ToList()を使用してください。数行しかない場合は正常に動作しますが、約1,000の場合は約です。 2.2秒、約12,000行に増やすと、フィルタが適用されていない、つまりすべてのアクティブな広告が返されたときに、ページが読み込まれるまでに32秒かかりました。
.Skipと.Takeを呼び出す前にすべての広告を引き出すのは、検索フォームで利用できるフィルタが、アクティブであるすべての現在の広告の可能なオプションに基づいているということです。製造業者のテーブル(ユーザーが検索結果のないメーカーを選択できる)から製造元のリストを選択するだけです。例えば
VehicleManufacturers = (from vm in FilteredAdverts.Select(x => x.VehicleManufacturer).Distinct().OrderBy(x => x)
select new SearchOptionsModel
{
Value = vm,
Text = vm,
Count = FilteredAdvertsVM.Where(x => x.VehicleManufacturer == vm).Count(),
})
.... filters for model, mileage etc
私が達成しようとしていることを知りたい場合は、Autotraderウェブサイトの検索フォームをご覧ください。
モデルがビューに渡される直前にすべてのフィルタが適用されると、.Skipと.Takeが適用されますが、今度はすべての行がプルされています。
私の質問は、これをやり直すにはどうすればいいですか?広告エンティティクラスでこれらのマップされていないプロパティを使用するより良い方法はありますか?私は自宅のPCで動作しています - C2D @ 3.4GHz、2GB RAM - 低速のクエリは不動産のウェブホストでOKですか?