我是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();
答案 0 :(得分:0)
从Owner
访问Select
属性会使CommonPartHandler
中的惰性加载器要求内容管理器加载用户内容项:_contentManager.Get<IUser>(part.Record.OwnerId)
。对于您的查询,每个内容项都会发生一次,因此会根据您的问题导致选择n + 1,其中n = 1200
。
至少有两种方法可以避免这种情况: