利用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:空库,不含任何表. 二. ...
随机推荐
- linux-PAM
PAM(Pluggable Authentication Modules)即可插拔式认证模块,一种用户级别的认证方式,它也是当前Linux服务器普遍使用的认证方式. PAM认证原理:参考资料来自htt ...
- sortColors
Given an array with n objects colored red, white or blue, sort them in-place so that objects of the ...
- 【Android - 进阶】之Drawable简介
Drawable是什么?Android给我们的解释是:“A general abstraction for 'something that can be drawn'.”,翻译过来就是:对于可以绘制的 ...
- c# 窗体开发2 高级控件的使用
1.单选按钮(RadioButton) 同一组中其他单选按钮不能同时选定 分组形式:panel GoupBox 窗体 方法: 属性 说明 Appearance RadioButton 控件的显示与命令 ...
- Dictionary的遍历
Dictionary<string, int> list = new Dictionary<string, int>(); list.Add("d", 1) ...
- .Net Core3.1下使用Swagger搭建web api项目
前言:微软于前天发布.net core 3.1正式版,并将长期支持3.1.所以我听到这个消息后就急忙下载.net core 3.1的SDK和Runtime,应该是公司最先用3.1的攻城狮了
- 基于PyTorch实现MNIST手写字识别
本篇不涉及模型原理,只是分享下代码.想要了解模型原理的可以去看网上很多大牛的博客. 目前代码实现了CNN和LSTM两个网络,整个代码分为四部分: Config:项目中涉及的参数: CNN:卷积神经网络 ...
- .Net Core Web Api使用模型验证验证参数合法性
在接口开发过程中免不了要去验证参数的合法性,模型验证就是帮助我们去验证参数的合法性,我们可以在需要验证的model属性上加上Data Annotations特性后就会自动帮我们在action前去验证输 ...
- CSS给元素清除浮动影响的方法,--最全四种方法
代码实例: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- hibernate查询方式(四)
---恢复内容开始--- 1.mysql中的多表联合查询 ****/*内连接查询*/ 只显示两个表有关联的记录 //第一种 SELECT * FROM Class c ,Student s WHER ...