使用XRM SDK的Dynamics CRM速度缓慢?

时间:2017-01-22 13:18:11

标签: asp.net angularjs dynamics-crm crm xrm

我们正在开发一个使用Microsoft Dynamics CRM连接到XRM SDK的系统,它的服务器端构建在.NET MVC上,前端端基于 Angularjs < / p>

我们在API响应中面临延迟问题,例如。登录API至少需要 1.8秒来检索成功或错误响应,而且这个API是最快的。

其他API甚至更慢,我们试图抓住这种缓慢的来源以便修复它,但没有运气。它是XRM SDK,API还是CRM本身。

如果你能提供帮助。

var cols = new ColumnSet("exdyn_employeecontractid", "exdyn_contractstatus");
            var secondEntityCols = new ColumnSet("exdyn_companyagreementid", "exdyn_agreementstatus");

            var filter = new FilterExpression
            {
                Conditions =
                {
                    new ConditionExpression
                    {
                        AttributeName = "exdyn_employeeid",
                        Operator = ConditionOperator.Equal,
                        Values = {model.EmployeeId}
                    },
                    new ConditionExpression
                    {
                        AttributeName = "exdyn_contractstatus",
                        Operator = ConditionOperator.Equal,
                        Values = { 3 } // approved {2} signed
                    },

                },

                FilterOperator = LogicalOperator.And
            };
            var secondFilter = new FilterExpression
            {
                Conditions =
                {
                    new ConditionExpression
                    {
                        AttributeName = "exdyn_agreementstatus",
                        Operator = ConditionOperator.Equal,
                        Values = { 2 } // active {2}
                    }
                }
            };

            var entity = _organizationService.GetEntityCollectionWithJoin
                ("exdyn_employeecontract", "exdyn_companyagreement",
                "exdyn_companyagreementid", "exdyn_companyagreementid", JoinOperator.Inner,
                cols, secondEntityCols, filter, secondFilter).Entities.FirstOrDefault();

==============

代码用于连接:

public class WebModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            // Register your Web API controllers.
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
            // Register your MVC controllers.
            builder.RegisterControllers(Assembly.GetExecutingAssembly());
            // OPTIONAL: Register web abstractions like HttpContextBase.
            builder.RegisterModule<AutofacWebTypesModule>();
            builder.RegisterFilterProvider();
            builder.Register(c => new WebConfigurationSettings()).As<IWebSettings>().SingleInstance();
            builder.Register(GetOrganizationServiceManagement).SingleInstance();
            builder.Register(GetOrganizationProxy).InstancePerRequest();
            builder.Register(c => new ExceptionHandler()).SingleInstance();

            builder.Register(c => new EmployeeService(c.Resolve<IOrganizationService>()))
                .As<IEmployeeService>()
                .EnableInterfaceInterceptors()
                .InterceptedBy(typeof(ExceptionHandler))
                .InstancePerRequest();
            builder.Register(c => new AttendanceService(c.Resolve<IOrganizationService>()))
                .As<IAttendanceService>().EnableInterfaceInterceptors()
                .InterceptedBy(typeof(ExceptionHandler))
                .InstancePerRequest();

            builder.Register(c => new ContractService(c.Resolve<IOrganizationService>()))
                .As<IContractService>().EnableInterfaceInterceptors()
                .InterceptedBy(typeof(ExceptionHandler))
                .InstancePerRequest();

            builder.Register(c => new InquiryService(c.Resolve<IOrganizationService>(), c.Resolve<ILookupService>()))
                .As<IInquiryService>().EnableInterfaceInterceptors()
                .InterceptedBy(typeof(ExceptionHandler))
                .InstancePerRequest();

            builder.Register(c => new LookupService(c.Resolve<IOrganizationService>()))
                .As<ILookupService>().EnableInterfaceInterceptors()
                .InterceptedBy(typeof(ExceptionHandler))
                .InstancePerRequest();

            builder.Register(c => new LeaveRequestService(c.Resolve<IOrganizationService>(),
                c.Resolve<IContractService>(), c.Resolve<ILookupService>()))
                .As<ILeaveRequestService>().EnableInterfaceInterceptors()
                .InterceptedBy(typeof(ExceptionHandler))
                .InstancePerRequest();


            builder.Register(c => new PurchaseRequestService(c.Resolve<IOrganizationService>(), c.Resolve<ILookupService>()))
                .As<IPurchaseRequestService>().EnableInterfaceInterceptors()
                .InterceptedBy(typeof(ExceptionHandler))
                .InstancePerRequest();

            builder.Register(c => new NotificationService(c.Resolve<IOrganizationService>()))
                .As<INotificationService>().EnableInterfaceInterceptors()
                .InterceptedBy(typeof(ExceptionHandler))
                .InstancePerRequest();
            builder.Register(c => new CacheClient())
                .As<ICacheClient>()
                .SingleInstance();
        }

        private static IServiceManagement<IOrganizationService> GetOrganizationServiceManagement(IComponentContext ctx)
        {
            var settings = ctx.Resolve<IWebSettings>();

            return ServiceConfigurationFactory.CreateManagement<IOrganizationService>(
                       new Uri(settings.OrganizationUrl));
        }

        private static IOrganizationService GetOrganizationProxy(IComponentContext ctx)
        {
            var svcMgmt = ctx.Resolve<IServiceManagement<IOrganizationService>>();
            var settings = ctx.Resolve<IWebSettings>();
            var credentials = new AuthenticationCredentials();
            credentials.ClientCredentials.UserName.UserName = settings.SystemUserName;
            credentials.ClientCredentials.UserName.Password = settings.SystemUserPassword;
            var authCredentials = svcMgmt.Authenticate(credentials);
            //return new OrganizationServiceProxy(svcMgmt, authCredentials.SecurityTokenResponse);
            return new OrganizationServiceProxy(svcMgmt, authCredentials.ClientCredentials);
        }

    }

1 个答案:

答案 0 :(得分:1)

它最有可能是CRM / API。你应该能够用像Fiddler这样的东西测试一下,看看正在发出的请求,并确定缓慢发生的地方。例如,以下是使用旧版SDK查询CRM在线沙箱:

var connection = CrmConnection.Parse(@"Url=https://ORG.crm.dynamics.com;Username=USERNAME;Password=PASSWORD");  
_orgService = new OrganizationService(connection);

_orgService.RetrieveMultiple(new FetchExpression(@"<fetch><entity name='account'><attribute name='accountid'/></entity></fetch>"));

检查提琴手,您会看到以下内容:

enter image description here

  1. 客户端有大约4个单独的HTTP请求,需要认证大约需要1.5秒(在这种情况下,它纯粹是O365用户,不使用ADFS)
  2. 最终的HTTP请求是返回5k帐户ID的实际查询。返回需要约5秒钟。
  3. 如果您对代码进行计时并与实际的HTTP请求进行比较,您可以看到花费的时间,但我敢打赌它将是请求,而不是SDK。

    您可以采取一些措施来尝试优化查询:

    1. 仅返回所需数据
    2. 限制联接数量
    3. 确保插件未在要查询的实体的RetrieveMultiple上运行。
    4. 验证一次并重复使用&#34;连接&#34;。 (根据您使用的SDK版本以及该SDK的哪些部分可以通过不同的方式完成。CrmServiceClient现在默认缓存,其他连接字符串具有Service Configuration Instance Mode等选项。