从CommonPart访问信息非常慢?

问题描述 投票:0回答:1

我是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();
c# orchardcms
1个回答
0
投票

Owner访问Select属性会导致CommonPartHandler中的延迟加载程序要求内容管理器加载用户内容项:_contentManager.Get<IUser>(part.Record.OwnerId)。对于查询中的每个内容项结果,这会发生一次,因此根据您的问题产生选择n + 1,其中n = 1200

至少有两种方法可以避免这种情况:

  1. 您可以使用HQL并制作一个查询,在1次操作中为您提供所需的一切。
  2. 您可以创建第一个内容管理器查询以获取所有者ID的集合,然后针对这些ID进行第二次内容管理器查询,并获得所需的一切,总共2个查询而不是1201。
© www.soinside.com 2019 - 2024. All rights reserved.