我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面的微软最有价值专家(Microsoft MVP),欢迎关注我的微信公众号 MSFTDynamics365erLuoYong ,回复351或者20190816可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!

利用标准的导入功能来导入数据是基本操作,操作起来简单引用,比较受用户喜欢,而且导入速度也可以,特别是并行导入的情况下。

最近碰到用CSV来导入数据,在导入之前将数据拆分成多个CSV文件,每个文件不超过8M,这些CSV文件打包成Zip文件后不超过32MB,上传后是差不多一个一个处理,并行处理没有那么明显了。如下图,我最开始用一个csv上传了一个文件进行导入,后面我用一个zip包上传了5个csv文件来导入,这个zip文件中的5个文件要会等到第一个处理完毕后再开始。然后zip中的文件有些并行处理,但是看起来不明显,下图可以看到 data02.csv 和 data03.csv都处于解析阶段。

我的印象中,Dynamics 365 CRM V8.X是可以并行导入的,而且处理速度挺快的,是Dynamics 365 Customer Engagement V9.X开始因为调用API的限制等并行不是那么厉害了吗?如果是,谁看到哪儿有说明请告知我,我更新下本博文,可由什么参数可以更改此类设置。

我查看了导入相关的部署属性,参考 Update deployment configuration settings ,查看的命令参考如下:

  1. Add-PSSnapin Microsoft.Crm.PowerShell
  2. Get-CrmSetting ImportSettings

我的环境显示结果如下,这些值应该是默认值。

如果是一个文件一个文件导入,速度不会很快,我们可以用程序来导入,多线程加上ExecuteMultipleRequest消息速度还是可以的。

  • 导入文件的文件名尽量用字母数字,不要包括空格,汉字,特殊符号等。
  • CSV文件的编码是UTF-8,而不是ANSI,因为ANSI编码不支持中文,导入后会发现中文是乱码!
  • 导入尽量用CSV格式,而不是Excel。
  • 对于有1:N关系的实体导入,最好能从源头生成GUID作为父实体的主键,然后导入子实体的时候直接利用前面生成的GUID,这样处理速度会快很多。
  • 对于每行记录最好有一个惟一键,如果没有可以用自增列(或者Excel生成一个序号)或者GUID作为惟一键,这样方便后续或者后台比较数据导入的成果。
  • 如果导入消息执行非常快,可能会碰上调用API的限制,调用API的限制请参考官方文档:API Limits ,这个时候通过ExecuteMultipleRequest消息和使用不同的账号来执行可以降低概率。
  • 如果可以,为每个要导入的文件准备一个整数,作为导入记录的 importsequencenumber 字段值,方便分析每个文件导入数据的情况。
  • 最好每个文件的行数不要超过10万,因为情况下导出记录到Excel的条数是10万。
  • 导入的程序最好放到服务器上运行,提升连接速度,同时也一般不容易像自己的机器一样关机或者重启会中断导入

我这里贴一个导入的代码:

  1. using Microsoft.Xrm.Sdk;
  2. using Microsoft.Xrm.Sdk.Client;
  3. using Microsoft.Xrm.Sdk.Messages;
  4. using System;
  5. using System.Configuration;
  6. using System.IO;
  7. using System.ServiceModel;
  8. using System.Threading;
  9.  
  10. namespace BulkImportRecords
  11. {
  12. class Program
  13. {
  14. public static IServiceManagement<IOrganizationService> sm;
  15. public static AuthenticationCredentials authCredentials;
  16. static int importsequencenumberstartat = Convert.ToInt32(ConfigurationManager.AppSettings["importsequencenumberstartat"]);
  17. static int threadcount = Convert.ToInt32(ConfigurationManager.AppSettings["threadcount"]);
  18. static void Main(string[] args)
  19. {
  20. sm = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(ConfigurationManager.AppSettings["orgUrl"]));
  21. authCredentials = new AuthenticationCredentials();
  22. authCredentials.ClientCredentials.UserName.UserName = ConfigurationManager.AppSettings["userName"];
  23. authCredentials.ClientCredentials.UserName.Password = ConfigurationManager.AppSettings["passWord"];
  24. authCredentials = sm.Authenticate(authCredentials);
  25. try
  26. {
  27. for (var i = ; i < threadcount; i++)
  28. {
  29. Thread newThread = new Thread(new ParameterizedThreadStart(Work));
  30. newThread.Start(i);
  31. }
  32. Console.ReadKey();
  33. }
  34. catch (FaultException ex)
  35. {
  36. Console.WriteLine("程序出现异常:ex.Message=" + ex.Message);
  37. Console.ReadKey();
  38. }
  39. }
  40.  
  41. static void Work(object data)
  42. {
  43. try
  44. {
  45. Console.WriteLine("线程开始" + DateTime.Now.ToLongTimeString() + ";线程ID:" + Thread.CurrentThread.ManagedThreadId + ";接收的参数值为:" + data.ToString());
  46. int importsequencenumber = importsequencenumberstartat + Convert.ToInt32(data);
  47. OrganizationServiceProxy orgSvc = new OrganizationServiceProxy(sm, authCredentials.ClientCredentials);
  48. //OrganizationServiceProxy orgSvc = new OrganizationServiceProxy(sm, authCredentials.SecurityTokenResponse);
  49. //ManagedTokenOrganizationServiceProxy orgSvc = new ManagedTokenOrganizationServiceProxy(sm, authCredentials.ClientCredentials);
  50. string strReadFilePath = ConfigurationManager.AppSettings["filename"];
  51. int i = ;
  52. int j = ;
  53. int z = ;
  54. ExecuteMultipleRequest multiReqs = new ExecuteMultipleRequest()
  55. {
  56. Settings = new ExecuteMultipleSettings()
  57. {
  58. ContinueOnError = true,
  59. ReturnResponses = false
  60. },
  61. Requests = new OrganizationRequestCollection()
  62. };
  63. using (StreamReader srReadFile = new StreamReader(string.Format(strReadFilePath, (Convert.ToInt32(data) + ).ToString(""))))
  64. {
  65. while (!srReadFile.EndOfStream)
  66. {
  67. string strReadLine = srReadFile.ReadLine(); //读取每行数据
  68. if (i != )//如果第一行包括标题的话要过滤掉
  69. {
  70. var arrLine = strReadLine.Split(',');
  71. CreateRequest req = new CreateRequest();
  72. var createEntity = new Entity("ly_test");
  73. createEntity["ly_name"] = arrLine[];
  74. createEntity["ly_singletext1"] = arrLine[];
  75. createEntity["ly_singletext2"] = arrLine[];
  76. createEntity["ly_singletext3"] = arrLine[];
  77. createEntity["importsequencenumber"] = Convert.ToInt32(importsequencenumber);
  78. req.Target = createEntity;
  79. if (j <= )
  80. {
  81. multiReqs.Requests.Add(req);
  82. }
  83. else
  84. {
  85. multiReqs.Requests = new OrganizationRequestCollection();
  86. multiReqs.Requests.Add(req);
  87. j = ;
  88. }
  89. if (j == )
  90. {
  91. orgSvc.Execute(multiReqs);
  92. Console.WriteLine("线程:" + Thread.CurrentThread.ManagedThreadId + "-导入完毕" + z + "条" + DateTime.Now.ToString());
  93. }
  94. z++;
  95. j++;
  96. }
  97. i++;
  98. }
  99. }
  100. orgSvc.Execute(multiReqs);
  101. Console.WriteLine("线程结束" + DateTime.Now.ToLongTimeString() + ";线程ID:" + Thread.CurrentThread.ManagedThreadId);
  102. }
  103. catch(FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex)
  104. {
  105. Console.WriteLine("执行遇到异常:" + ex.Detail.ErrorCode + ex.Message + ex.StackTrace);
  106. }
  107. catch (Exception e)
  108. {
  109. Console.WriteLine("执行遇到异常:" + e.Message + e.StackTrace);
  110. }
  111. }
  112. }
  113. }

这个程序配合的配置文件如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <configuration>
  3. <startup>
  4. <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
  5. </startup>
  6. <appSettings>
  7. <add key="userName" value="crmadmin@luoyong.me"/>
  8. <add key="passWord" value="Pass"/>
  9. <add key="orgUrl" value="https://demo.luoyong.me/XRMServices/2011/Organization.svc"/>
  10. <add key="filename" value="D:\dataimport\data{0}.csv"/>
  11. <add key="importsequencenumberstartat" value="1000000"/>
  12. <add key="threadcount" value="10"/>
  13. </appSettings>
  14. </configuration>

Dynamics 365 Customer Engagement的标准导入不支持并行导入了吗?的更多相关文章

  1. 利用Dynamics 365 Customer Engagement的标准导入功能导入附件。

    我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...

  2. Dynamics 365 Customer Engagement导入解决方案时出错:Microsoft.Crm.CrmException: Plug-in assembly does not contain the required types or assembly content cannot be updated.

    我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...

  3. 利用Azure虚拟机安装Dynamics 365 Customer Engagement之二:创建域控虚拟机

    我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...

  4. 如何让用户登录Dynamics 365 Customer Engagement后自动登录到Unified Interface App?

    微软动态CRM专家罗勇 ,回复324或者20190422可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me! Dynamics 365 Customer Engagement ...

  5. Dynamics 365 Customer Engagement中插件的调试

    微软动态CRM专家罗勇 ,回复319或者20190319可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 本文主要根据官方的教 ...

  6. 下载Dynamics 365 Customer Engagement 工具

    微软动态CRM专家罗勇 ,回复312或者20190311可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 从Dynamics ...

  7. Dynamics 365 Customer Engagement安装FAQ

    微软动态CRM专家罗勇 ,回复310或者20190308可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 本文参考了包括但不限 ...

  8. Dynamics 365 Customer Engagement V9 活动源功能报错的解决方法

    微软动态CRM专家罗勇 ,回复300或者20190120可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 安装好Dynamic ...

  9. 配置基于服务器认证的Dynamics 365 Customer Engagement和SharePoint Online集成

    我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...

随机推荐

  1. 失去循环标签的Python,我这样实现跳出外层循环

    不完美的Python 自从各类Python大火,感觉天上地下哪儿都有Python的一席之地,Python功夫好啊-但python有些细节上缺少其他语言的便利.今天我们就来举几个例子. 跳出外层循环 大 ...

  2. windows7 上安装python3.8步骤

    今天给小白们写一个在windows7 上安装python3.8的过程. 1.先到https://www.python.org/downloads/官网下载最新版的python, 不要到别的下载网站去下 ...

  3. Object.defineProperty和Object.freeze、Object.seal

    目录 一 Object.defineProperty 1.1 用法 1.2 数据描述 1.2.1 value 1.2.2 writable 1.2.3 enumerable 1.2.4 configu ...

  4. npm 安装/删除/发布/更新/撤销 发布包

    目录 一. npm安装包 1.1 什么时候用本地/全局安装? 1 当你试图安装命令行工具的时候,例如 grunt CLI的时候,使用全局安装 2. 当你试图通过npm install 某个模块,并通过 ...

  5. openlayers4 入门开发系列之前端动态渲染克里金插值 kriging 篇(附源码下载)

    前言 openlayers4 官网的 api 文档介绍地址 openlayers4 api,里面详细的介绍 openlayers4 各个类的介绍,还有就是在线例子:openlayers4 官网在线例子 ...

  6. React中setState学习总结

    react中setState方法到底是异步还是同步,其实这个是分在什么条件下是异步或者同步. 1.先来回顾一下react组件中改变state的几种方式: import React, { Compone ...

  7. 真伪随机数 ——Random和SecureRandom

    Random Random用来创建伪随机数.所谓伪随机数,是指只要给定一个初始的种子,产生的随机数序列是完全一样的. 要生成一个随机数,可以使用nextInt().nextLong().nextFlo ...

  8. ELK和EFK的区别

    ELK 是现阶段众多企业单位都在使用的一种日志分析系统,它能够方便的为我们收集你想要的日志并且展示出来 ELK是Elasticsearch.Logstash.Kibana的简称,这三者都是开源软件,通 ...

  9. webpack学习_管理输出(管理资源插件)

    管理输出步骤 Step1:在src新建文件print.js添加逻辑 Step2:在src/index.js import 引用新添加的逻辑 Step3:更新dist/index.html文件,修改引入 ...

  10. Django模型层—ORM

    目录 一.模型层(models) 1-1. 常用的字段类型 1-2. 字段参数 1-3. 自定义char字段 1-4. 外键关系 二.Django中测试脚本的使用 三.单表操作 3-1. 添加记录 3 ...