我怎么知道Linq表达式已被自动编译并且查询计划被缓存了?

时间:2015-04-02 13:12:45

标签: sql sql-server entity-framework entity-framework-6 profiler

我在使用EF 6的.Net 4.5应用程序中有一个非常复杂的LINQ to SQL表达式。结果是一个非常非常长的SQL查询,大约2700行。

这是一个在我的服务类中调用方法的简单测试。

    [TestMethod]
    public void InmatningsmallServiceGetRows()
    {
        Guid id = new Guid("33a274f7-add7-49d7-ab0a-097d52e779ae");
        var children = ArchiveWork.ArchService.getChildrenByParentId(id).ToList();
        Assert.AreEqual(children.Count(), 0);
    }

在我的服务类中:

public IQueryable<ArchiveRow> getChildrenByParentId(Guid id)
{
    var qChildren = (from rel in ArchiveRelRepo.Query()
         where rel.source_fk == id && rel.typ_fk == CodeArchiveRelation.Direct
         select rel
               );

    var qArchiveChildren = (from rel in qChildren
          let a = rel.table_archive_dest
          let date = a.table_archive_dates.FirstOrDefault(d => d.enhet_fk == a.enhet_id && d.datetyp_fk == CodeDateType.DTime)
          let relsToChildren = a.table_archive_rel_source
          let backwardRel = a.table_archive_rel_dest
          let term = a.table_archive_term
          orderby rel.sortkey
          select new ArchiveRow
          {
              Id = a.enhet_id,
              TypCode = a.typ_fk,
              IncrementalNumber = SqlFunctions.StringConvert((double)a.incNumber).Trim(),
              Title = a.name,
              From = date.startdate,
              Tom = date.slutdate,
              SortKey = rel.sortkey,
              NumberOfChildren = relsToChildren.Where(r => r.typ_fk == CodeArchiveRelation.Direct).Count(),
              TypeOfChildren = relsToChildren.Where(r => r.typ_fk == CodeArchiveRelation.Direct).Select(x => x.table_archive_dest.typ_fk).Distinct(),
              NumberOfReproduced = relsToChildren.Count(rr => rr.typ_fk == CodeArchiveRelation.Reproduced),
              NumberOfReferences_source = relsToChildren.Where(rh => rh.typ_fk == CodeArchiveRelation.SeAven || rh.typ_fk == CodeArchiveRelation.Se).Count(),
              NumberOfReferences_dest = backwardRel.Where(rl => rl.typ_fk == CodeArchiveRelation.Se).Count(),
              ArchivesReferencesSource = relsToChildren.Where(rh => rh.typ_fk == CodeArchiveRelation.SeAven || rh.typ_fk == CodeArchiveRelation.Se).Select(x => new Archive { ReferensCodeBas = x.table_archive_dest.referenceCode, Title = x.table_archive_dest.name }),
              ArchivesReferencesDest = backwardRel.Where(rl => rl.typ_fk == CodeArchiveRelation.Se).Select(x => new Archive { ReferensCodeBas = x.table_archive_source.referenceCode, Titel = x.table_archive_source.name }),
              TopographyReferences = term.Where(y => y.table_term.tes_fk == CodeTesaurus.Topography).Select(x => new ReferencesTerm { TermName = x.table_term.name, Specifikation = x.spec }),
              AmnesOrdReferences = term.Where(y => y.table_term.tes_fk != CodeTesaurus.Topography).Select(x => new ReferencesTerm { TermName = x.table_term.name, Specifikation = x.spec }),
              InstitutionReferences = a.table_archive_institution.Select(x => x.table_institution).Select(r => new Institution { referenceCode = r.referenceCode, Name = r.name }),
              LocationReferences = a.table_location_archive.Select(x => new LocationsReference { FranHyllaText = x.table_location_start.referenceCode, TillHyllaText = x.table_location_slut.referenceCode }),
              KallTyper = relsToChildren.Select(x => new ArkivTypRelTyp { RelTyp = x.typ_fk, ArkivTyp = x.table_archive_dest.typ_fk }),
              DestTyper = backwardRel.Select(x => new ArkivTypRelTyp { RelTyp = x.typ_fk, ArkivTyp = x.table_archive_source.typ_fk })
          }
       );

    return qArchiveChildren;
}

我运行测试,大约需要6秒钟才能完成 enter image description here

但在Profiler中,实际查询似乎执行得非常快。 enter image description here

整个操作以和审核登录和注销开始,耗时超过5秒。在此期间发生了什么(我们称之为初始连接时间,ICT *)?

如果我运行一个非常简单的测试,只是在同一个dbContext中调用Find方法,它的初始连接时间约为3400毫秒。这似乎是某种最短的连接时间。 但是什么使这个持续时间增加了? 我有其他同样复杂的查询,信息通信技术超过5700毫秒,信息通信技术约为3500毫秒。

是否可以防止自动编译,EF每次都重新编译LINQ表达式? 有没有办法知道查询是否已编译并且查询计划是否已缓存?

(*)ICT是我自己的命名法。

0 个答案:

没有答案