实体框架存储过程结果到域模型

时间:2016-06-28 15:37:35

标签: c# entity-framework lambda

我正在尝试使用更快的旧项目。我目前正在寻找一些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吃得最多。所以我假设微软已经对这些方法进行了优化,加快速度的唯一方法就是在程序中使一些变量不可为空。这个问题具有误导性,如此深奥,我认为它不属于这里,只会让人迷惑。抱歉。

1 个答案:

答案 0 :(得分:1)

您应该拆分代码并检查哪个代码花费时间。

public IEnumerable<DomainModelResult> GetData()
{
    var lst = this.EntityFrameworkDB.GetDataSproc().ToList();
    return lst
           .Select(sprocResults=>sprocResults.ToDomainModelResult())
           .AsEnumerable();
}

我很确定GetDataSproc程序占用了大部分时间。您需要优化存储过程代码

<强>更新 如果可能的话,最好在SQL端做更多工作,而不是在内存中检索60,000行。几种可能的解决方案:

  • 如果您需要显示此信息,请执行分页(顶部和跳过)
  • 如果您在内存中检索行后进行任何过滤或计算或分组,请在存储过程中执行此操作
  • .Net方面,当您返回IEnumerable时,您可以在第二部分使用yield,取决于您的架构