我正在使用EF6
我有一个通用表,该表使用“每个层次的表”方法保存不同类型的类对象的数据。另外,这些类对象使用复杂的类型来为其属性定义类型。
因此,使用一个虚构的示例,
表=人员
“老师的麦克”是Person类型为“老师”的Person的“老师”实例
“教师”实例具有2个属性,complextypePersonalDetails和complextypeAddress。
complextypePersonalDetails包含 名,姓和年龄。
complextypeAddress包含 房屋名称,街道,镇,市,县。
我承认这种设计可能是最上层的,问题可能出在我的制作上,但除此之外,我想检查一下我是否可以在改写EF6之前再使用它。
我正在使用JetBrains DotTrace对代码进行性能分析。
在第一个电话上说 personTeacher = db.person.OfType()。First()
我得到了大约150,000ms的巨大延迟
周围:
SerializedGeneratedViewOfType (150,000ms)
TryGenerateQueryViewOfType
GenerateTypeSpecificQueryView
GenerateQueryViewForSingleExtent
GenerateQueryViewForExtentAndType
GenerateViewsForExtentAndType
GenerateViewComponents
EnsureExtentIsFullyMapped (90,000ms)
GenerateCaseStatements (60,000ms)
我使用创建SQL的“ InteractivePreGeneratedViews” nuget包创建了一个预生成的视图。但是即使如此,我仍然需要引起我的第一击。此外,每次重新启动Webserver / Website / AppPool时,这种情况似乎都会发生。
我不能完全确定EF流程,但是我想Web应用程序启动时会发生其他形式的运行时编译或缓存。这可能在哪里发生,有没有一种我可以用来预先生成/预编译/预缓存此问题的主动方法。
从中期来看,我们将在Dapper或EF.Core中重写此代码。所以现在,对可以做什么有什么想法?
谢谢。
答案 0 :(得分:3)
我之前对此进行了评论,但撤回了它,但只是同意“这种设计可能太过头了,问题可能出在我身上”,但我想我可以看看是否有人参与进来。
最初的启动成本是由于EF需要解析您的架构映射。第一次访问上下文中的DBSet时,这种情况就会发生一次。您可以通过在应用程序启动时执行查询来缓解这种情况,即
void Application_Start(object sender, EventArgs e)
{
// Initialization stuff...
using (var context = new MyContext())
{
var result = context.MyTable.Any(); // Spin up will happen here, not when the first user attempts to access a query.
}
}
实际上,您需要对DbContext运行查询以解决映射,只是一个新的操作就无法完成。
对于更大或更复杂的模式,您还可以利用有限的上下文,其中每个上下文针对应用程序的特定区域映射一组特定的关系。上下文越不复杂/不全面,则其初始化速度越快。
就设计而言,TPH用于表示继承,这是您需要在相似实体之间建立“ is-a”关系的地方。关系模型和按定义的ORM可以支持这一点,但是它们更适合于“具有”关系。与其建立模型“是一个有地址的人”,不如将关系最好地映射为一个人可能“有一个地址”。我已经在一个由工程师团队设计的系统上工作,该系统由6个表表示具有动态规则的整个报告系统。老实说,这些设计是一场噩梦。