4

目前,当我们从我们的网站查询 CRM 时,我们的网站面临响应时间缓慢(超过 1 分钟)的问题。我们通过 Web 服务使用 CRM 2011。当我们进行调查时,我们发现时间都花在了查询 CRM 上。

我们使用 CrmSvcUtil.exe 来生成映射到 CRM 实体的代理类。然后,我们使用带有 C# 的 LINQ 创建上下文实例并查询 CRM。

当我们查询时,我们使用 LINQ to CRM 加载父对象,然后使用 LoadProperty 加载相关的子对象。

我想知道是否有人使用其他查询 CRM 的方法,以及您在实施过程中是否遇到过此类问题。

我在下面包含了一个简化的示例查询。

    public void SelectEventById(Guid id)
     {
            var crmEventDelivery = this.ServiceContext.EventDeliverySet.FirstOrDefault(eventDelivery => eventDelivery.Id == id);
            if (crmEventDelivery != null)
            {
              this.SelectCrmEventDeliveryWithRelationships(crmEventDelivery);
            }
    }

    private void SelectCrmEventDeliveryWithRelationships(EventDelivery crmEventDelivery)
     {
            // Loading List of Venue Delivery on parent crmEventDelivery thats been passed
            this.ServiceContext.LoadProperty(crmEventDelivery, Attributes.EventDelivery.eventdelivery_venuedelivery);

            foreach (var venueDelivery in crmEventDelivery.eventdelivery_venuedelivery)
            {
                 // Loading Venue on each Venue Delivery
                 ServiceContext.LoadProperty(venueDelivery, Attributes.VenueDelivery.venue_venuedelivery);
            }

            // Loading List of Session Delivery on parent crmEventDelivery thats been passed
            this.ServiceContext.LoadProperty(crmEventDelivery, Attributes.EventDelivery.eventdelivery_sessiondelivery);

            foreach (var sessionDelivery in crmEventDelivery.eventdelivery_sessiondelivery)
            {
              // Loading Presenters on each Session Delivery
              ServiceContext.LoadProperty(sessionDelivery, Attributes.SessionDelivery.sessiondelivery_presenterbooking);
            }
   }
4

5 回答 5

4

就像其他答案中提到的那样,您的主要问题是 Web 服务调用的数量。没有人提到的是,您可以使用查询连接通过一次调用来检索许多对象。所以你可以尝试这样的事情:

var query_join = (from e in ServiceContext.EventDeliverySet
                         join v in ServiceContext.VenueDeliverySet on e.EventDeliveryId equals v.EvendDeliveryId.Id
                         join vn in ServiceContext.VenueSet on v.VenueDeliveryId equals vn.VenueDeliveryId.Id
                         join s in ServiceContext.SessionDeliverSet on e.EventDeliveryId equals s.EvendDeliveryId.Id
                         where e.EventDeliveryId == id // *improtant (see below)
                         select new { EventDelivery = e, VenueDelivery = v, Venue = vn, SessionDeliver = s }).ToList();

然后您可以在 query_join 上运行 foreach 并将其放在一起。

***重要:不要使用基本 Id 属性(e.Id),坚持使用 e.EntityNameId.Value(不知道为什么,但我花了一段时间才弄清楚。Id 返回默认 Guid 值“00000 ..”)。

于 2013-05-18T20:59:44.933 回答
3

根据您提供的内容,这看起来像是一个标准的延迟加载问题,除了我的猜测是每个延迟加载都会导致 Web 服务调用。这将被称为“健谈”服务架构。您的目标应该是尽可能少地调用服务来检索单个请求的数据。

调用以填写详细信息似乎是一个好主意,因为您可以在只需要 1 或 2 级深度或一直向下的数据的情况下重复使用单独的服务方法,但会付出巨大的性能损失。

在这种情况下,您最好定义一个返回完整对象图的 Web 服务调用。我不知道您是否/什么用于 CRM 中的 ORM 层,但如果您进行特定调用以获取完整的交付图,那么 ORM 可以将数据急切地提取到更少的 SQL 语句中。更少调用 Web 服务(以及随后更少调用 CRM 数据存储)应该会显着提高您的性能。

于 2012-09-11T01:27:22.280 回答
1

在尝试了其他答案中的所有建议技巧并进行了进一步分析之后,在我们使用 CRM 的特定场景中,以及它是如何设置的——我们决定简单地绕过它

我们最终使用了一些内置视图,这不是 CRM 文档中推荐的方法,但我们确实需要实现更高的性能,而这种情况下的 CRM 方法正好挡住了我们的路。

对于其他阅读本文的人,也请参阅其他答案。

于 2013-04-14T11:39:46.490 回答
1

所以我明白为什么这可能需要一段时间。我认为正如其他人所评论的那样,您正在进行相当多的网络服务调用。如果您有时间了解单个呼叫是否很慢或者仅仅是因为您拨打了很多电话会很有趣,我建议对此进行分析。

无论如何,我怀疑不使用强类型实体会获得更好的性能。

我建议使用 FetchXml 查询,这将允许您构建 Sql Xml 样式查询。基本上,您应该能够用一个呼叫替换您的许多我们 bservice 呼叫。MSDN有一个示例,还可以查看Stunnware FetchXml 设计器,产品 > Stunnware 工具 > 下载和评估。它是为 Crm 4 构建的,但几乎支持您需要的所有功能。

如果您不喜欢,您也可以尝试使用QueryExpressionOData,这两种方法都可以让您一键获取数据。

于 2012-09-11T20:04:00.563 回答
0

因为查询不知道以后会需要哪些字段,所以当select子句中只指定实体时,所有列都从实体返回。为了仅指定您将使用的字段,您必须在 select 子句中返回一个新对象,指定您要使用的字段。

所以代替这个:

var accounts = from acct in xrm.AccountSet
               where acct.Name.StartsWith("Test")
               select acct;

用这个:

var accounts = from acct in xrm.AccountSet
               where acct.Name.StartsWith("Test")
               select new Account()
               {
                   AccountId = acct.AccountId,
                   Name = acct.Name
               };

查看这篇文章的更多详细信息。

到 Linq 还是不到 Linq

于 2014-08-21T01:05:33.560 回答