1

プロジェクトでは、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秒半かかります。

しかし、私はまだ提案を受け付けています。

ありがとう

クリスチャン

4

1 に答える 1

0

When I've reviewed your query I could figure out that you are querying the database objects int your query.

It will be much more faster if you push your logic in database and get the result in LINQ.

于 2012-11-20T12:02:58.270 に答える