我在使用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秒钟才能完成
但在Profiler中,实际查询似乎执行得非常快。
整个操作以和审核登录和注销开始,耗时超过5秒。在此期间发生了什么(我们称之为初始连接时间,ICT *)?
如果我运行一个非常简单的测试,只是在同一个dbContext中调用Find方法,它的初始连接时间约为3400毫秒。这似乎是某种最短的连接时间。 但是什么使这个持续时间增加了? 我有其他同样复杂的查询,信息通信技术超过5700毫秒,信息通信技术约为3500毫秒。
是否可以防止自动编译,EF每次都重新编译LINQ表达式? 有没有办法知道查询是否已编译并且查询计划是否已缓存?
(*)ICT是我自己的命名法。