プロジェクトでは、EntityFrameworkで既存のテーブルを使用する必要がありました。これは、検索関数の1つの大きなlinqクエリで解決されました。現在、この関数は10件の結果に対して3秒ほどかかります。
問題は、誰かがこのlinqを改善するためのポイントを知っているかどうかです。
これはlinqクエリです:
var result = (from o in db.Objects
join omsc in db.Omschrijvingen on o.Omschrijving_Identifier equals omsc.Identifier
join a in db.Adressen on o.Adres_Id equals a.Adres_Id
join oa in db.Object_Abonnement on o.Object_Id equals oa.Object_ID
join oaf in db.Object_Afbeeldingen on o.Object_Id equals oaf.Object_Id
where o.Enabled && oaf.StandaardAfbeelding == true &&
(!iType.Any() || iType.Contains(o.Type_Id)) &&
(iProvince < 1 || a.Provincie_Id == iProvince) &&
(iDepartement < 1 || a.Departement_Id == iDepartement) &&
o.Object_Logs.All(
ol => ol.Log_Type != (int) ApplicationDefinitions.LogTypes.Deleted) &&
(oa.Betaald && oa.Tot >= DateTime.Now) &&
(!kenmerken.Any() ||
db.Object_Kenmerken.Count(
ken =>
kenmerken.Contains(ken.Kenmerk_Id) && ken.Object_Id == o.Object_Id &&
ken.Waarde.ToUpper() != "FALSE" && ken.Waarde != "0") == kenmerken.Count()) &&
(search.Length < 1 || omsc.Naam.ToLower().Contains(search.ToLower()) ||
omsc.Omschrijving.ToLower().Contains(search.ToLower()) ||
a.Woonplaats.ToLower().Contains(search.ToLower()))
select new FullObject
{
Object_Id = o.Object_Id,
Adres_Id = a.Adres_Id,
DepartmentId = a.Departement_Id,
Department = (a.Departementen != null) ? a.Departementen.Naam : "",
ProviciesId = a.Provincie_Id,
Provicie = (a.Provicies != null) ? a.Provicies.Naam : "",
Contact_Id = o.Contact_Id,
Naam = omsc.Naam,
Omschrijving = omsc.Omschrijving,
Prijs =
(((db.Prijs_Periode.Where(pp => pp.Object_Id == o.Object_Id).Min(
pp => pp.Prijs_Dag) > 0)
? db.Prijs_Periode.Where(pp => pp.Object_Id == o.Object_Id).
Min(pp => pp.Prijs_Dag)
: db.Prijs_Periode.Where(pp => pp.Object_Id == o.Object_Id).
Min(pp => pp.Prijs_Week)) > 0)
? (db.Prijs_Periode.Where(pp => pp.Object_Id == o.Object_Id).
Min
(pp => pp.Prijs_Dag) > 0)
? db.Prijs_Periode
.Where(
pp => pp.Object_Id == o.Object_Id)
.Min(pp => pp.Prijs_Dag)
: db.Prijs_Periode
.Where(
pp => pp.Object_Id == o.Object_Id)
.Min(pp => pp.Prijs_Week/7)
: (db.Prijs_Periode
.Where(pp => pp.Object_Id == o.Object_Id)
.Min(pp => pp.Prijs_Weekend) > 0)
? db.Prijs_Periode
.Where(
pp => pp.Object_Id == o.Object_Id)
.Min(pp => pp.Prijs_Weekend/3)
: (db.Prijs_Periode
.Where(
pp => pp.Object_Id == o.Object_Id)
.Min(pp => pp.Prijs_Midweek) > 0)
? db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id)
.Min(pp => pp.Prijs_Midweek/14)
: (db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id)
.Min(pp => pp.Prijs_Langweekend) >
0)
? db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id)
.Min(
pp =>
pp.Prijs_Langweekend)
: 0,
SPrijs = (((db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Dag) > 0)
? db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Dag)
: db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Week)) > 0)
? (db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Dag) > 0)
? db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Dag)
: db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Week/7)
: (db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Weekend) > 0)
? db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Weekend/3)
: (db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Midweek) > 0)
? db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Midweek/14)
: (db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Langweekend) >
0)
? db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(
pp =>
pp.Prijs_Langweekend)
: 0,
Personen =
(db.Object_Kenmerken.Any(
iok =>
iok.Kenmerk_Id == iAantalPersonenId &&
iok.Object_Id == o.Object_Id))
? db.Object_Kenmerken.Where(
iok =>
iok.Kenmerk_Id == iAantalPersonenId &&
iok.Object_Id == o.Object_Id).Select(
iok => EntitiesFunctions.ParseInt(iok.Waarde)).
FirstOrDefault()
: 0,
Slaapkamers =
(db.Object_Kenmerken.Any(
iok =>
iok.Kenmerk_Id == iAantalSlaapkamersId &&
iok.Object_Id == o.Object_Id))
? db.Object_Kenmerken.Where(
iok =>
iok.Kenmerk_Id == iAantalSlaapkamersId &&
iok.Object_Id == o.Object_Id).Select(
iok => EntitiesFunctions.ParseInt(iok.Waarde)).
FirstOrDefault()
: 0,
UrlKey = omsc.UrlKey,
Title = omsc.Title,
Plaats = a.Woonplaats,
Enabled = o.Enabled,
GoogleMap_Url = o.GoogleMap_Url,
InkoopPrijs = o.InkoopPrijs,
Type_Id = o.Type_Id,
Website = o.Website,
Adressen = o.Adressen,
Thumb = oaf.Tumbnial
}
)
.Where(item => (item.Prijs >= minPrice || minPrice == 0) &&
(item.Prijs <= maxPrice || maxPrice == 0) &&
(bOffersOnly == false || item.Prijs < item.SPrijs) &&
(item.Personen >= personen || personen == 0) &&
(item.Slaapkamers == slaapkamers || slaapkamers == 0))
.Distinct();
より明確にするために:
次のオブジェクトを取得する必要があります。
public class FullObject
{
public int Object_Id { get; set; }
public int? Adres_Id { get; set; }
public int Contact_Id { get; set; }
public string Naam { get; set; }
public string Omschrijving { get; set; }
public decimal? Prijs { get; set; }
public decimal? SPrijs { get; set; }
public int Personen { get; set; }
public int Slaapkamers { get; set; }
public string UrlKey { get; set; }
public string Title { get; set; }
public string Plaats { get; set; }
public int ProviciesId { get; set; }
public string Provicie { get; set; }
public int? DepartmentId { get; set; }
public string Department { get; set; }
public bool Enabled { get; set; }
public string GoogleMap_Url { get; set; }
public decimal? InkoopPrijs { get; set; }
public int Type_Id { get; set; }
public string Website { get; set; }
public List<Data.Object_Kenmerken> ItemKenmerken { get; set; }
public Data.Adressen Adressen { get; set; }
public string Thumb { get; set; }
}
次のことをフィルタリングする必要があります
int[] iType
string search
int[] kenmerken
int iProvince
int iDepartement
decimal minPrice
decimal maxPrice
int personen
int slaapkamers
bool bOffersOnly
そして、これは(少しの)テーブル構造です:
http://i.stack.imgur.com/3Y0Tf.jpg
すべてを個別に取得しようとしましたが、データベースに多数のオブジェクトがあるため、合計12秒(および増加)になり、フィルタリングのためにすべてを取得する必要があります。
誰かがこれを挑戦だと思って、私が見落としていたものを見ることを願っています。
前もって感謝します。
クリスチャン
このチケットは閉鎖されているので、私の答えは次のとおりです。
すべての返信をありがとう。
最高は@Daniel-Hilgarthからのものでした。計算をクエリに入れないようにします。15分ごとに実行されるSQLジョブで計算を実行し、結果を直接Objectテーブルに配置することを選択したことを修正しました。
その次に、データベースロジックへの結合を少し変更しました。@Micheal-Samteladzeに感謝します。
このすべての変更により、次のクエリが得られます。
var result = (from o in db.Objects
join omsc in db.Omschrijvingen on o.Omschrijving_Identifier equals omsc.Identifier
where o.Enabled &&
(!iType.Any() || iType.Contains(o.Type_Id)) &&
(o.Prijs >= minPrice || minPrice == 0) &&
(o.Prijs <= maxPrice || maxPrice == 0) &&
(bOffersOnly == false || o.Prijs < o.SPrijs) &&
(o.Personen >= personen || personen == 0) &&
(o.Kamers == slaapkamers || slaapkamers == 0) &&
(iProvince < 1 || o.Adressen.Provincie_Id == iProvince) &&
(iDepartement < 1 || o.Adressen.Departement_Id == iDepartement) &&
o.Object_Logs.All(ol => ol.Log_Type != (int) ApplicationDefinitions.LogTypes.Deleted) &&
o.Object_Abonnement.Any(oa => oa.Betaald && oa.Tot >= DateTime.Now) &&
(!kenmerken.Any() || o.Object_Kenmerken.Count(ken => kenmerken.Contains(ken.Kenmerk_Id) && ken.Object_Id == o.Object_Id && ken.Waarde.ToUpper() != "FALSE" && ken.Waarde != "0") == kenmerken.Count()) &&
(search.Length < 1 || omsc.Naam.ToLower().Contains(search.ToLower()) || omsc.Omschrijving.ToLower().Contains(search.ToLower()) || o.Adressen.Woonplaats.ToLower().Contains(search.ToLower()))
select new FullObject
{
Object_Id = o.Object_Id,
Adres_Id = o.Adressen.Adres_Id,
DepartmentId = o.Adressen.Departement_Id,
Department = (o.Adressen.Departementen != null) ? o.Adressen.Departementen.Naam : "",
ProviciesId = o.Adressen.Provincie_Id,
Provicie = (o.Adressen.Provicies != null) ? o.Adressen.Provicies.Naam : "",
Contact_Id = o.Contact_Id,
Naam = omsc.Naam,
Omschrijving = omsc.Omschrijving,
Prijs = o.Prijs ?? 0,
SPrijs = o.SPrijs ?? 0,
Personen = o.Personen,
Slaapkamers = 0,
UrlKey = omsc.UrlKey,
Title = omsc.Title,
Plaats = o.Adressen.Woonplaats,
Enabled = o.Enabled,
GoogleMap_Url = o.GoogleMap_Url,
InkoopPrijs = o.InkoopPrijs,
Type_Id = o.Type_Id,
Website = o.Website,
Adressen = o.Adressen,
Thumb = o.Object_Afbeeldingen.FirstOrDefault(af => af.StandaardAfbeelding).Tumbnial
}
)
.Distinct();
これは、古いものが最低3をとった最初の10の結果を与えるのに、約1秒半かかります。
しかし、私はまだ提案を受け付けています。
ありがとう
クリスチャン