如何配置Package Deployer实现指定顺序导入解决方案与数据文件?
解决Package Deployer自定义导入顺序的问题
默认情况下,Package Deployer会先完成<solutions>节点下所有解决方案的导入,再执行数据导入操作,因此仅通过修改ImportConfig.xml无法实现「先导Solution1/2 → 再导数据 → 最后导Solution3」的顺序,必须通过自定义代码扩展Package Deployer的逻辑。
实现步骤:
- 创建自定义部署类
新建一个类继承自PackageDeployerBase,重写Run方法,分三阶段执行导入:
using Microsoft.Crm.Sdk.Messages; using Microsoft.Xrm.Tooling.PackageDeployment.CrmPackageExtentionBase; using System; using System.Collections.Generic; public class CustomPackageDeployer : PackageDeployerBase { public override void Run(IXrmServiceContext context, Dictionary<string, string> configSettings, List<PackageLogInfo> logCollection) { // 阶段1:导入Solution1和Solution2 ImportSolution(context, "Solution1.zip"); ImportSolution(context, "Solution2.zip"); // 阶段2:导入数据文件 ImportData(context, "BookingStatusSchema.xml", "BookingStatusData.zip"); // 阶段3:导入Solution3 ImportSolution(context, "Solution3.zip"); } // 封装解决方案导入方法 private void ImportSolution(IXrmServiceContext context, string solutionFileName) { var solutionPath = GetPackageLocation() + "\\" + solutionFileName; var importRequest = new ImportSolutionRequest { CustomizationFile = System.IO.File.ReadAllBytes(solutionPath), OverwriteUnmanagedCustomizations = true, PublishWorkflows = true }; context.Execute(importRequest); Log("已成功导入解决方案:" + solutionFileName); } // 封装数据导入方法 private void ImportData(IXrmServiceContext context, string schemaFileName, string dataFileName) { // 先导入数据映射 var schemaPath = GetPackageLocation() + "\\" + schemaFileName; var importMapRequest = new ImportMappingsImportMapRequest { ImportMap = System.IO.File.ReadAllBytes(schemaPath), ReplaceIds = true }; context.Execute(importMapRequest); Log("已成功导入数据映射:" + schemaFileName); // 导入数据文件 var dataPath = GetPackageLocation() + "\\" + dataFileName; var importDataRequest = new ImportDataRequest { DataFile = System.IO.File.ReadAllBytes(dataPath), ImportMapId = GetImportMapId(context, "BookingStatusSchema"), ProcessDuplicates = new ProcessDuplicatesRequest { DuplicateDetectionEnabled = true, IgnoreDuplicates = false } }; context.Execute(importDataRequest); Log("已成功导入数据文件:" + dataFileName); } // 根据映射名称获取ImportMap的ID private Guid GetImportMapId(IXrmServiceContext context, string mapName) { var query = new Microsoft.Xrm.Sdk.Query.QueryExpression("importmap") { ColumnSet = new Microsoft.Xrm.Sdk.Query.ColumnSet("importmapid"), Criteria = new Microsoft.Xrm.Sdk.Query.FilterExpression { Conditions = { new Microsoft.Xrm.Sdk.Query.ConditionExpression("name", Microsoft.Xrm.Sdk.Query.ConditionOperator.Equal, mapName) } } }; var result = context.RetrieveMultiple(query); return result.Entities[0].Id; } public override string GetCustomValidationErrorMessage() { return string.Empty; } }
- 修改ImportConfig.xml
将Solution3从<solutions>节点中移除,避免默认流程自动导入,修改后的配置如下:
<?xml version="1.0" encoding="utf-16"?> <configdatastorage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" installsampledata="false" waitforsampledatatoinstall="true" agentdesktopzipfile="" agentdesktopexename="" crmmigdataimportfile="BookingStatusData.zip"> <!-- 仅保留默认阶段导入的Solution1和Solution2 --> <solutions> <configsolutionfile solutionpackagefilename="Solution1.zip" /> <configsolutionfile solutionpackagefilename="Solution2.zip" /> </solutions> <filesmapstoimport> <configimportmapfile filename="BookingStatusSchema.xml" /> </filesmapstoimport> <filestoimport> <configimportfile filename="BookingStatusData.zip" filetype="ZIP" associatedmap="BookingStatusSchema" importtoentity="bookingstatus" datadelimiter="" fielddelimiter="comma" enableduplicatedetection="true" isfirstrowheader="true" isrecordownerateam="false" owneruser="" waitforimporttocomplete="false" /> </filestoimport> </configdatastorage>
- 配置项目属性
在Package Deployer项目的PackageFolder中确保所有文件(解决方案、数据文件、映射文件)已正确放置,并在项目属性中设置自定义部署类为入口点。
关键说明:
- 自定义代码通过直接调用CRM SDK的请求控制导入顺序,完全覆盖默认部署流程
GetPackageLocation()方法用于获取PackageFolder的绝对路径,确保正确读取部署文件- 数据导入需先导入映射文件,再导入数据,代码中已封装这两个步骤
内容的提问来源于stack exchange,提问作者Nachiket
相关产品推荐
相关产品推荐

