我是Orchard的新手,这必须涉及如何存储基础数据。
与CommonPart
的加入似乎足够快,像这样:
var items = _contentManager.Query<MyUserPart, MyUserPartRecord>("someTypeName")
.ForVersion(VersionOptions.Published)
.Join<CommonPartRecord>().List().ToList();
这运行得相当快。但每当我尝试访问CommonPart
中的某个字段时,它运行速度非常慢,如下所示:
var items = _contentManager.Query<MyUserPart, MyUserPartRecord>("someTypeName")
.ForVersion(VersionOptions.Published)
.Join<CommonPartRecord>().List()
//access some field from commonpart
.Select(e => new {
User = e.As<CommonPart>().Owner.UserName
}).ToList();
总数据只是1200
项目,它需要的时间是关于5 seconds
,它不能像那样慢。对于在后台运行的简单SQL查询,它应该花费大约0.5秒甚至更短的时间。
我曾尝试调查Orchard的源代码,但没有发现任何问题。在IContent
的访问点,一切似乎都进入了黑盒子。我希望有人能给我一些诊断和解决这个难题的建议。谢谢!
更新:
我试过调试了一下,发现在DefaultContentManager
中遇到了以下方法:
ContentItem New(string contentType) { ... }
嗯,这真的很有趣,查询只是在不修改,插入和更新任何内容的情况下询问数据。但是这种被击中的方法表明这里出了点问题。
更新:
有了@Bertrand Le Roy的评论,我用QueryHint
尝试了以下代码,但看起来它没有改变任何东西:
var items = _contentManager.Query<MyUserPart, MyUserPartRecord>("someTypeName")
.ForVersion(VersionOptions.Published)
.Join<CommonPartRecord>()
.WithQueryHints(new QueryHints().ExpandParts<CommonPart>())
.List()
//access some field from commonpart
.Select(e => new {
User = e.As<CommonPart>().Owner.UserName
}).ToList();
这个(没有.Join
)
var items = _contentManager.Query<MyUserPart, MyUserPartRecord>("someTypeName")
.ForVersion(VersionOptions.Published)
.WithQueryHints(new QueryHints().ExpandParts<CommonPart>())
.List()
//access some field from commonpart
.Select(e => new {
User = e.As<CommonPart>().Owner.UserName
}).ToList();
从Owner
访问Select
属性会导致CommonPartHandler
中的延迟加载程序要求内容管理器加载用户内容项:_contentManager.Get<IUser>(part.Record.OwnerId)
。对于查询中的每个内容项结果,这会发生一次,因此根据您的问题产生选择n + 1,其中n = 1200
。
至少有两种方法可以避免这种情况: