利用ExecuteMultipleRequest来批量导入数据,成功的成功失败的失败,并生成导入结果文件
我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面的微软最有价值专家(Microsoft MVP),欢迎关注我的微信公众号 MSFTDynamics365erLuoYong ,回复377或者20191109可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!
我前面的博文 Dynamics 365 Customer Engagement的标准导入不支持并行导入了吗? 提供了多进程使用ExecuteMultipleRequest导入数据的程序,速度虽然挺快的,但是有一个问题,导入失败的并不知道是哪些,没有办法统计,这里我改善一下。
关于ExecuteMultipleRequest,请参考官方文档,Use ExecuteMultiple to improve performance for bulk data load ,官方代码示例请参考 ExecuteMultipleRequest Class ,本博文参考了Magnetism 的Dynamics CRM ExecuteMultipleResponse – Analysing the Results 。
要做到成功的成功,失败的失败,记得要将 ExecuteMultipleSettings 的 ContinueOnError 设置为 true,要记录失败的原因记得要将 ExecuteMultipleSettings 的 ReturnResponses 设置为 true。
直接上代码:
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Messages;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.ServiceModel;
using System.Threading; namespace BulkImportRecords
{
class Program
{
public static IServiceManagement<IOrganizationService> sm;
public static AuthenticationCredentials authCredentials;
static int importsequencenumberstartat = Convert.ToInt32(ConfigurationManager.AppSettings["importsequencenumberstartat"]);
static int threadcount = Convert.ToInt32(ConfigurationManager.AppSettings["threadcount"]);
static string resultFile = ConfigurationManager.AppSettings["resultFile"];
static void Main(string[] args)
{
sm = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(ConfigurationManager.AppSettings["orgUrl"]));
authCredentials = new AuthenticationCredentials();
authCredentials.ClientCredentials.UserName.UserName = ConfigurationManager.AppSettings["userName"];
authCredentials.ClientCredentials.UserName.Password = ConfigurationManager.AppSettings["passWord"];
authCredentials = sm.Authenticate(authCredentials);
try
{
for (var i = ; i < threadcount; i++)
{
Thread newThread = new Thread(new ParameterizedThreadStart(Work));
newThread.Start(i);
}
Console.ReadKey();
}
catch (FaultException ex)
{
Console.WriteLine("程序出现异常:ex.Message=" + ex.Message);
Console.ReadKey();
}
} static void Work(object data)
{
ExecuteMultipleResponse multiRep;
List<string> content = new List<string>();
try
{
Console.WriteLine("线程开始" + DateTime.Now.ToLongTimeString() + ";线程ID:" + Thread.CurrentThread.ManagedThreadId + ";接收的参数值为:" + data.ToString());
int importsequencenumber = importsequencenumberstartat + Convert.ToInt32(data);
OrganizationServiceProxy orgSvc = new OrganizationServiceProxy(sm, authCredentials.ClientCredentials);
string strReadFilePath = ConfigurationManager.AppSettings["filename"];
int i = ;
int j = ;
int z = ;
ExecuteMultipleRequest multiReqs = new ExecuteMultipleRequest()
{
Settings = new ExecuteMultipleSettings()
{
ContinueOnError = true,
ReturnResponses = true
},
Requests = new OrganizationRequestCollection()
};
using (StreamReader srReadFile = new StreamReader(string.Format(strReadFilePath, (Convert.ToInt32(data) + ).ToString(""))))
{
while (!srReadFile.EndOfStream)
{
string strReadLine = srReadFile.ReadLine(); //读取每行数据
if (i != )//如果第一行包括标题的话要过滤掉
{
content.Add(strReadLine);
var arrLine = strReadLine.Split(',');
CreateRequest req = new CreateRequest();
var createEntity = new Entity("ly_test");
createEntity["ly_name"] = arrLine[];
createEntity["ly_singletext1"] = arrLine[];
createEntity["ly_singletext2"] = arrLine[];
createEntity["ly_singletext3"] = arrLine[];
createEntity["importsequencenumber"] = Convert.ToInt32(importsequencenumber);
req.Target = createEntity;
if (j <= )
{
multiReqs.Requests.Add(req);
}
else
{
multiReqs.Requests = new OrganizationRequestCollection();
multiReqs.Requests.Add(req);
j = ;
}
if (j == )
{
multiRep = (ExecuteMultipleResponse)orgSvc.Execute(multiReqs);
foreach(var Rep in multiRep.Responses)
{
if(Rep.Fault != null)
{
File.AppendAllText(string.Format(resultFile, (Convert.ToInt32(data) + ).ToString("")), $"{content[z*1000+Rep.RequestIndex+1]},FAIL,{Rep.Fault.Message}" + Environment.NewLine);
}
else
{
File.AppendAllText(string.Format(resultFile, (Convert.ToInt32(data) + ).ToString("")), $"{content[z * 1000 + Rep.RequestIndex+1]},OK,{((CreateResponse)Rep.Response).id}" + Environment.NewLine);
}
}
z++;
Console.WriteLine("线程:" + Thread.CurrentThread.ManagedThreadId + "-导入完毕" + z* + "条" + DateTime.Now.ToString());
}
j++;
}
else
{
content.Add($"{strReadLine},结果,消息");
File.AppendAllText(string.Format(resultFile, (Convert.ToInt32(data) + ).ToString("")), content[] + Environment.NewLine);
}
i++;
}
}
multiRep = (ExecuteMultipleResponse)orgSvc.Execute(multiReqs);
foreach (var Rep in multiRep.Responses)
{
if (Rep.Fault != null)
{
File.AppendAllText(string.Format(resultFile, (Convert.ToInt32(data) + ).ToString("")), $"{content[z * 1000 + Rep.RequestIndex+1]},FAIL,{Rep.Fault.Message}" + Environment.NewLine);
}
else
{
File.AppendAllText(string.Format(resultFile, (Convert.ToInt32(data) + ).ToString("")), $"{content[z * 1000 + Rep.RequestIndex+1]},OK,{((CreateResponse)Rep.Response).id}" + Environment.NewLine);
}
}
Console.WriteLine("线程结束" + DateTime.Now.ToLongTimeString() + ";线程ID:" + Thread.CurrentThread.ManagedThreadId);
}
catch(FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex)
{
Console.WriteLine("执行遇到异常:" + ex.Detail.ErrorCode + ex.Message + ex.StackTrace);
}
catch (Exception e)
{
Console.WriteLine("执行遇到异常:" + e.Message + e.StackTrace);
}
}
}
}
配套的app.config内容如下:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup>
<appSettings>
<add key="userName" value="crmadmin@luoyong.me"/>
<add key="passWord" value="Password"/>
<add key="orgUrl" value="https://demo.luoyong.me/XRMServices/2011/Organization.svc"/>
<add key="filename" value="D:\dataimport\data{0}.csv"/>
<add key="importsequencenumberstartat" value="1000000"/>
<add key="threadcount" value="2"/>
<add key="resultFile" value="D:\ImportResult{0}.csv"/>
</appSettings>
</configuration>
为了看到测试效果,我对要导入的实体新建了一个实时工作流如下,如果测试实体的名称字段包括5或者6就以【已取消】的状态停止工作流,并设置好错误信息。

然后我就执行后看到生成的执行结果CSV文件如下,如果CSV文件用Excel打开中文是乱码,就将CSV文件以 UTF-8 with BOM 编码格式另存为一下就可以了。
可以看到有成功,有失败的,失败的告知的原因也是正确的,插入记录成功的记录了插入记录后该记录的主键ID。

利用ExecuteMultipleRequest来批量导入数据,成功的成功失败的失败,并生成导入结果文件的更多相关文章
- 利用DataTable快速批量导数据
DataSet ds = new DataSet(); using (SqlConnection conn = new SqlConnection(@"data sou ...
- 使用kettle来根据时间戳或者批次号来批量导入数据,达到增量的效果。
1.Kettle是一款国外开源的ETL工具,纯java编写,可以在Window.Linux.Unix上运行,数据抽取高效稳定.下载图形化界面的zip包格式的,直接解压缩使用即可.安装部署模式这里不说了 ...
- 随笔编号-09 批量导入数据(Mysql)报MySQL server has gone away 问题的解决方法
问题场景: 使用*.sql 脚本,批量导入数据到mysql实例中,使用DOS 界面导入的,期间,到最后一步 source D:\aaa.sql 回车后,系统提示 MySQL server has g ...
- Excel表格导入数据
步骤: 1,选择要插入的数据库--右键--任务--导入数据 2,点击下一步,选择数据源,excel文件路径,和版本信息(注:使用2010及以上版本的office,请先将格式转换为03 或07格式的以便 ...
- ThinkPHP+uploadify+upload+PHPExcel 无刷新导入数据
前端HTML+JQuery 备注Jquery需要1.x版本,不能用2.x版本 1.引入必要文件及上传input <load file="__PUBLIC__/js/jquery-1. ...
- 用代码从文件中导入数据到SQL Server
引言 导入数据到SQL Server 是常见的需求,特别是定期导入这种需求. 对于定期导入主要有以下几种方式可选择: Bulk Insert Bcp Utility OpenRowSet 写程序导入( ...
- geotrellis使用(二十一)自动导入数据
目录 前言 整体介绍 前台界面 后台控制 总结 一.前言 之前Geotrellis数据导入集群采用的是命令行的方式,即通过命令行提交spark任务来ingest数据,待数据导入完毕再启动 ...
- oracle 导出数据和导入数据
导出数据 exp zl_gj/zlkj@gqxt grants=y tables=(zl_gj.ckgj,zl_gj.gjlx,zl_gj.rkgj) file=c:\gj.dmp log=c:\g ...
- SQL Server 2008 导出数据与导入数据任务介绍
一. 实例数据库介绍 源数据库Test_Other_DB:存在tb_Class,tb_Student,tb_TestTable三张表. 目标数据库TestDB_Output:空库,不含任何表. 二. ...
随机推荐
- python的匿名函数
在Python,有两种函数,一种是def定义,一种是lambda函数. lambda函数是Python一种生成函数对象的表达式形式.匿名函数通常是创建了可以被调用的函数,它返回了函数,而并没有将这个函 ...
- 剑指Offer-32.丑数(C++/Java)
题目: 把只包含质因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含质因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 分析: ...
- Win10无法安装.NET Framework3.5的解决办法
诸位网友如果工作中使用WIN10遇到如图的这种问题,现将解决办法整理如下: 一.第一步就是修复系统:按“Windows+X”点击“Windows PowerShell(管理员)&命令提示符(管 ...
- 处理器CPU天梯图,显卡天梯图(性能排名图)
自己网上找的几个图,仅供参考,买电脑可以看看了~
- (python)查看糗事百科文字 点赞 作者 等级 评论
import requestsimport reheaders = { 'User-Agent':'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; ...
- Scheme实现数字电路仿真(1)——组合电路
EDA是个很大的话题,本系列只针对其中一小部分,数字电路的仿真,叙述一点概念性的东西,并不会过于深入,这方面的内容实则是无底洞.本系列并不是真的要做EDA,按照SICP里的相关内容,采用Lisp的方言 ...
- tp5判断多模块下访问PC端和手机端
现在很多网站的手机端和PC端都是分开的模块,这是问题就来了,有些手机端的用户输入了PC端的网址,直接访问了PC端.下面我教大家如何实现手机端用户访问PC时,跳转回手机端. 解决方法:把下面的代码放到公 ...
- Docker数据挂载
Docker数据管理 在容器中管理数据主要有两种方式: 数据卷(Volumes) 挂载主机目录(Bind mounts) 数据卷 数据卷是一个可供一个或多个容器使用的特殊目录,它绕过UFS,可以提供很 ...
- NIM游戏,NIM游戏变形,威佐夫博弈以及巴什博奕总结
NIM游戏,NIM游戏变形,威佐夫博弈以及巴什博奕总结 经典NIM游戏: 一共有N堆石子,编号1..n,第i堆中有个a[i]个石子. 每一次操作Alice和Bob可以从任意一堆石子中取出任意数量的石子 ...
- POJ1458 Subsquence
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. ...