แชร์ผ่าน


การจัดเตรียมโซลูชันด้วยการนำเข้าและส่งออกแบบอะซิงโครนัส

คุณเคยประสบกับสถานการณ์ในระหว่างการนำเข้าหรือส่งออกโซลูชันขนาดใหญ่ที่การดำเนินการหมดเวลาหรือไม่ ถ้าใช่ คุณอาจเป็นผู้ที่มีสิทธิ์ในการดำเนินการนำเข้า/ส่งออกโซลูชันในแบบอะซิงโครนัส หัวข้อนี้อธิบายวิธีเริ่มต้นการนำเข้าหรือส่งออกแบบอะซิงโครนัสโดยใช้ Dataverse SDK สำหรับ .NET และ Web API

การจัดเตรียมโซลูชัน

ในการเปรียบเทียบกับการนำเข้าโซลูชันโดยที่มีการนำเข้าโซลูชันและพร้อมใช้งานในสภาพแวดล้อมทันที การจัดเตรียมจะแบ่งกระบวนการนำเข้าออกเป็นขั้นตอนที่ควบคุมได้มากขึ้น กระบวนการจัดเตรียมจะนำเข้าโซลูชันเป็นโซลูชัน "ที่ระงับ" โดยที่ผู้ดูแลระบบสามารถตัดสินใจได้ว่าจะให้ผู้ใช้ใช้งานโซลูชันที่จัดเตรียมได้เมื่อใดหรือจะทำการปรับรุ่น (ในกรณีของการปรับรุ่นโซลูชัน) ในสภาพแวดล้อมเป้าหมาย ส่วนหนึ่งของกระบวนการจัดเตรียมคือการตรวจสอบความถูกต้องของโซลูชันที่จัดเตรียม ด้วยวิธีนี้ คุณสามารถจัดเตรียมโซลูชันโดยที่รู้ว่าโซลูชันถูกต้อง และกำหนดเวลาที่จะใช้โซลูชันนั้นหรือปรับรุ่นเป็นสภาพแวดล้อมเป้าหมาย

การดำเนินการ API เว็บ Dataverse SDK สำหรับ .NET
จัดเตรียมโซลูชัน สเตจโซลูชั่น คำขอ StageSolution

ผลลัพธ์ของการจัดเตรียมจะเป็นการรวบรวมผลการตรวจสอบที่แสดงความสำเร็จหรือความล้มเหลวและ (หากสำเร็จ) StageSolutionUploadId ที่จะใช้ในการเรียก ImportSolutionAsync ดูโค้ดตัวอย่าง Web API ของโซลูชันการนำเข้าด้านบนสำหรับตัวอย่างวิธีการดำเนินการ

public static StageSolutionResults StageSolution(
    IOrganizationService service,
    string solutionFilePath)
{
  // Stage the solution
  var req = new StageSolutionRequest();

  byte[] fileBytes = File.ReadAllBytes(solutionFilePath);
  req["CustomizationFile"] = fileBytes;
  var res = service.Execute(req);

  return (res["StageSolutionResults"] as StageSolutionResults);
}

การนำเข้าโซลูชัน

ImportSolution คือการดำเนินการ (หรือข้อความ) ที่ดำเนินการนำเข้าแบบซิงโครนัส ในการดำเนินการนำเข้าแบบอะซิงโครนัส ให้ใช้ ImportSolutionAsync

การดำเนินการ API เว็บ Dataverse SDK สำหรับ .NET
นำเข้าโซลูชัน โซลูชันการนำเข้าแบบอะซิงก์ คำขอนำเข้าโซลูชัน Async

ตอนนี้มาดูตัวอย่างโค้ดที่แสดง ImportSolutionAsync

public static ImportSolutionAsyncResponse ImportSolution(
    IOrganizationService service,
    StageSolutionResults stagingResults,
    Dictionary<string,Guid> connectionIds,
    Dictionary<string,string> envarValues )
{
    // Import the staged solution
    var componentDetails = stagingResults.SolutionComponentsDetails;

    // TODO These are not referenced in the code but are useful to explore
    var missingDependencies = stagingResults.MissingDependencies;   // Contains missing dependencies
    var solutionDetails = stagingResults.SolutionDetails;           // Contains solution details

    var connectionReferences = componentDetails.Where(x => string.Equals(x.ComponentTypeName, "connectionreference"));
    var envVarDef = componentDetails.Where(x => string.Equals(x.ComponentTypeName, "environmentvariabledefinition"));
    var envVarValue = componentDetails.Where(x => string.Equals(x.ComponentTypeName, "environmentvariablevalue"));

    var componentParams = new EntityCollection();

    // Add each connection reference to the component parmameters entity collection.
    foreach (var conn in connectionReferences)
    {
        var e = new Entity("connectionreference")
        {
            ["connectionreferencelogicalname"] = conn.Attributes["connectionreferencelogicalname"].ToString(),
            ["connectionreferencedisplayname"] = conn.Attributes["connectionreferencedisplayname"].ToString(),
            ["connectorid"] = conn.Attributes["connectorid"].ToString(),
            ["connectionid"] = connectionIds[conn.ComponentName]
        };
        componentParams.Entities.Add(e);
    }
            
    // Add each environment variable to the component parmameters entity collection.
    foreach (var value in envVarValue)
    {
        var e = new Entity("environmentvariablevalue")
        {
            ["schemaname"] = value.Attributes["schemaname"].ToString(),
            ["value"] = envarValues[value.ComponentName]
        };

        if (value.Attributes.ContainsKey("environmentvariablevalueid"))
        {
            e["environmentvariablevalueid"] = value.Attributes["environmentvariablevalueid"].ToString();
        }
        componentParams.Entities.Add(e);
    }

    // Import the solution
    var importSolutionReq = new ImportSolutionAsyncRequest();
    importSolutionReq.ComponentParameters = componentParams;
    importSolutionReq.SolutionParameters = new SolutionParameters { StageSolutionUploadId = stagingResults.StageSolutionUploadId };
    var response = service.Execute(importSolutionReq) as ImportSolutionAsyncResponse;

    return (response);
}

ImportSolutionAsync แบ่งปันพารามิเตอร์อินพุตจำนวนมากด้วย ImportSolution แต่เพิ่ม ComponentParameters และ SolutionParameters - ComponentParameters สามารถใช้เพื่อเขียนทับข้อมูลส่วนประกอบในไฟล์ XML การปรับแต่งของโซลูชันได้ SolutionParameters สามารถนำมาใช้ในการส่งต่อ StageSolutionUploadId ของโซลูชันแบบขั้นตอนตามที่แสดงในโค้ดตัวอย่าง Web API ข้อมูลเพิ่มเติม: การจัดเตรียมโซลูชัน

คำตอบที่ส่งคืนมาจาก ImportSolutionAsync ประกอบด้วย ImportJobKey และ AsyncOperationId ค่า ImportJobKey สามารถใช้ค่าเพื่อให้ได้ผลลัพธ์การนำเข้าและค่า AsyncOperationId สามารถใช้เพื่อติดตามสถานะงานนำเข้า

public static void CheckImportStatus(
    IOrganizationService service,
    Guid asyncOperationId,
    Guid importJobKey)
{
    // Get solution import status
    var finished = false;
    Entity asyncOperation = null;
    // Wait until the async job is finished
    while (!finished)
    {
        asyncOperation = service.Retrieve("asyncoperation", asyncOperationId, new ColumnSet("statecode", "statuscode"));
        OptionSetValue statecode = (OptionSetValue)asyncOperation["statecode"];
        if (statecode.Value == 3)
        {
            finished = true;
        }
        else
        {
            Thread.Sleep(10000);
        }
    }
    // Solution import completed successfully
    OptionSetValue statuscode = (OptionSetValue)asyncOperation["statuscode"];
    if (statuscode.Value == 30)
    {
        Console.WriteLine("The solution import completed successfully.");
    }
    else if (asyncOperation["statuscode"].ToString() == "31")  // Solution import failed
    {
        Console.WriteLine("The solution import failed.");
        var getLogReq = new RetrieveFormattedImportJobResultsRequest { ImportJobId = importJobKey };
        var importJob = service.Execute(getLogReq) as RetrieveFormattedImportJobResultsResponse;
        // TODO Do something with the import job results
    }
}

การส่งออกโซลูชัน

ExportSolution คือการดำเนินการ (หรือข้อความ) ที่ดำเนินการส่งออกแบบซิงโครนัส ในการดำเนินการส่งออกแบบอะซิงโครนัส ให้ใช้ ExportSolutionAsync

การดำเนินการ API เว็บ Dataverse SDK สำหรับ .NET
ส่งออกโซลูชัน โซลูชันการส่งออกแบบอะซิงก์ คำขอส่งออกโซลูชัน Async
ดาวน์โหลดไฟล์โซลูชันที่ส่งออก ดาวน์โหลดโซลูชันส่งออกข้อมูล ดาวน์โหลดโซลูชันส่งออกข้อมูลคำขอ

ตอนนี้มาดูตัวอย่างโค้ดที่แสดง ExportSolutionAsync

// Where 'service' is a pre-configured IOrganizationService instance.
var service = (OrganizationServiceProxy)xsc.CreateOrganizationService();

var req = new OrganizationRequest("ExportSolutionAsync");
req.Parameters.Add("SolutionName", "ExportSolutionAsyncTest");
req.Parameters.Add("Managed", false);
var response = service.Execute(req);

ในคำตอบคือค่าของพารามิเตอร์ AsyncOperationId และ ExportJobId ใช้ AsyncOperationId ในการตอบกลับเพื่อยืนยันความสำเร็จ (statecode == 3; statuscode == 30) ของงานแบบอะซิงโครนัส จากนั้น ใช้การดำเนินการ DownloadSolutionExportData (หรือข้อความ) ที่มีค่า ExportJobId จากการตอบกลับการส่งออกเพื่อดาวน์โหลดไฟล์โซลูชันที่ส่งออก ซึ่งส่งคืนในพารามิเตอร์ ExportSolutionFile

// Where 'service' is a pre-configured IOrganizationService instance.
var service = (OrganizationServiceProxy)xsc.CreateOrganizationService();

var req = new OrganizationRequest("DownloadSolutionExportData");
req.Parameters.Add("ExportJobId", Guid.Parse("a9089b53-a1c7-ea11-a813-000d3a14420d");
var response = service.Execute(req);

ดูเพิ่มเติม

ตัวอย่าง: การจัดเตรียมโซลูชันด้วยการนำเข้าแบบอะซิงโครนัส