对于一个项目,我们不得不将现有的表与实体框架一起使用。这解决了搜索功能的 1 个大型 linq 查询。目前,此功能需要 3 秒才能获得 10 个结果。
问题是是否有人知道改进此 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();
这需要大约 1 秒半的时间才能给出前 10 个结果,而旧的结果至少需要 3 个。
但我仍然愿意接受建议。
谢谢
克里斯蒂安