我正在尝试使用更快的旧项目。我目前正在寻找一些Web API。一个API运行速度特别慢,问题出在它正在调用的数据服务中。具体来说,它是在lambda方法中尝试将存储过程结果映射到域模型。一个简单版本的代码。
public IEnumerable<DomainModelResult> GetData()
{
return this.EntityFrameworkDB.GetDataSproc().ToList()
.Select(sprocResults=>sprocResults.ToDomainModelResult())
.AsEnumerable();
}
这是一个简化版本,但在对其进行分析后,我发现主要的挂起是在lambda函数中。我假设这是因为EFContext仍然是开放的,并且正在发生一些愚蠢的实体框架。
问题是我对实体框架(实习生)相对较新,而且对它的内部工作方式一无所知。有人可以解释为什么这么慢。我认为它应该非常快DomainModelResult是一个POCO,并且在ToDomainModelResult中只使用了setter方法。
编辑:
我认为ToList()
会这样做,但开始怀疑自己,因为我想不出另一种解释。所有ToDomainModelResult()
内容都非常简单。像。的东西。
public static DomainModelResult ToDomainModelResult(SprocResult source)
{
return new DomainModeResult
{
FirstName = source.description,
MiddleName = source._middlename,
LastName = source.lastname,
UserName = source.expr2,
Address = source.uglyName
};
}
它只是一堆简单的setter,我认为造成问题的模型有17个属性。这样做的原因是因为项目首先是旧数据库,而存储过程具有丑陋的名称,根本不具有描述性。同样,在数据服务中切换存储过程也很容易,并且不会破坏项目的其余部分。
编辑:2由于某种原因使用ToArray
并拆分linq语句使得从过程结果到域模型结果的分配非常快。现在整个dataservice方法更快,这很奇怪,我不知道其余的时间去了哪里。
这可能是一个比我原先想象的更深奥的问题。我的问题没有得到解答,但问题不再存在。感谢所有回复。我现在仍然没有答案。
编辑3:请标记此问题以便删除我无法将其删除。我发现了问题,但这与我原来的问题完全无关。当我问这个问题时,我误解了这个问题。速度的提高我正在寻找编译器优化和在探查器中运行代码。真正的问题不是在我的lambda中,而是在实体框架调用的动态lambda中,当关闭上下文或访问对象时,它正在进行数据验证。 GetString,GetInt32和ISDBNull吃得最多。所以我假设微软已经对这些方法进行了优化,加快速度的唯一方法就是在程序中使一些变量不可为空。这个问题具有误导性,如此深奥,我认为它不属于这里,只会让人迷惑。抱歉。
答案 0 :(得分:1)
您应该拆分代码并检查哪个代码花费时间。
public IEnumerable<DomainModelResult> GetData()
{
var lst = this.EntityFrameworkDB.GetDataSproc().ToList();
return lst
.Select(sprocResults=>sprocResults.ToDomainModelResult())
.AsEnumerable();
}
我很确定GetDataSproc程序占用了大部分时间。您需要优化存储过程代码
<强>更新强> 如果可能的话,最好在SQL端做更多工作,而不是在内存中检索60,000行。几种可能的解决方案:
IEnumerable
时,您可以在第二部分使用yield
,取决于您的架构