EF Materialization在复杂的Where Query中很慢

时间:2016-03-07 08:49:44

标签: c# entity-framework entity-framework-6

我有以下查询:

context.tblBeauftPosMitarbs
    .Where(bpm => bpm.tblBeauftragungPosition.tblBeauftragung.tblProjekt.tblTasks.Any(t => t.tblZeitens.Any(z => z.Datum >= start &&
        z.Datum <= end &&
        employeeIds.Contains(z.MitarbeiterID))) ||
        bpm.tblBeauftragungPosition.tblBeauftragung.tblProjekt.tblZeitens.Any(z => z.Datum >= start &&
        z.Datum <= end &&
        employeeIds.Contains(z.MitarbeiterID)))
    .ToList();
  • 返回约700行。
  • 这需要在LINQPad中执行24秒。
  • 我正在使用EF 6.1数据库 第一
  • SQL生成几乎是即时的。
  • 我在SQL Management Studio中测试了查询,执行时间不到一秒。

我正在使用

context.Configuration.AutoDetectChangesEnabled = false;
context.Configuration.ProxyCreationEnabled = false; 
  • AsNoTracking()没有影响力。
  • Take(1)没有影响力。

简化Where(虽然它不再做它应该做的事情)将执行时间缩短一半(约12秒)

context.tblBeauftPosMitarbs
    .Where(bpm => bpm.tblBeauftragungPosition.tblBeauftragung.tblProjekt.tblTasks.Any(t => t.tblZeitens.Any(z => z.Datum >= start &&
        z.Datum <= end &&
        employeeIds.Contains(z.MitarbeiterID))))
    .ToList();

所以我的猜测是,当涉及复杂的Where语句时,EF需要更多的时间来实现,但我不知道为什么,因为Where应该只对SQL geeneration产生影响, SQL Server上的执行时间,而不是对象实现的执行时间。

修改

以下是实体类的代码。 PK是(BeauftragungIDBeauftPosNr

public partial class tblBeauftPosMitarb
{
    public int BeauftragungID { get; set; }
    public int BeauftPosNr { get; set; }
    public int MaID { get; set; }
    public System.DateTime Timestamp { get; set; }
    public Nullable<int> EinheitID { get; set; }
    public Nullable<double> Menge { get; set; }
    public Nullable<int> PreisgruppeID { get; set; }
    public Nullable<double> NettopreisProEinheit { get; set; }

    public virtual tblBeauftragungPosition tblBeauftragungPosition { get; set; }
    public virtual tblMitarbeiter tblMitarbeiter { get; set; }
    public virtual tblPositionstyp tblPositionstyp { get; set; }
    public virtual tblProjektPreisgruppe tblProjektPreisgruppe { get; set; }
}

我还尝试了以下操作,但对执行时间没有任何影响:

context.tblBeauftPosMitarbs
    .Where(bpm => bpm.tblBeauftragungPosition.tblBeauftragung.tblProjekt.tblTasks.Any(t => t.tblZeitens.Any(z => z.Datum >= start &&
        z.Datum <= end &&
        employeeIds.Contains(z.MitarbeiterID))) ||
        bpm.tblBeauftragungPosition.tblBeauftragung.tblProjekt.tblZeitens.Any(z => z.Datum >= start &&
        z.Datum <= end &&
        employeeIds.Contains(z.MitarbeiterID)))
    .Select(bpm => bpm.BeauftragungID)
    .ToList();

0 个答案:

没有答案