ทำงานกับโซลูชันที่ใช้ Dataverse SDK
เป็นส่วนหนึ่งของการพัฒนาวงจรชีวิตการผลิตของคุณ คุณอาจต้องการสร้างระบบอัตโนมัติที่กำหนดเองเพื่อจัดการกับงานบางอย่าง ตัวอย่างเช่น ในไปป์ไลน์โครงการ DevOps ของคุณ คุณอาจต้องการเรียกใช้งานโค้ดหรือสคริปต์ที่กำหนดเองที่สร้างสภาพแวดล้อมแบบ Sandbox นำเข้าโซลูชันที่ไม่มีการจัดการ ส่งออกโซลูชันที่ไม่มีการจัดการนั้นในฐานะเป็นโซลูชันที่มีการจัดการ และในที่สุดก็ลบสภาพแวดล้อม คุณสามารถทำสิ่งนี้และอื่นๆ โดยใช้ API ที่คุณสามารถใช้ได้ ด้านล่างนี้คือตัวอย่างบางส่วนของสิ่งที่คุณทำได้โดยใช้ Dataverse SDK สำหรับ .NET และโค้ดที่กำหนดเอง
หมายเหตุ
คุณสามารถทำการดำเนินการเดียวกันเหล่านี้ได้โดยใช้ Web API การกระทำที่เกี่ยวข้องคือ: ImportSolution, ExportSolution, CloneAsPatch และ CloneAsSolution
สร้าง นำเข้า หรือส่งออกโซลูชันที่ไม่มีการจัดการ
เรามาดูวิธีการดำิเนินงานของโซลูชันทั่วไป โดยใช้รหัส C# หากต้องการดูตัวอย่างโค้ด C# ที่ใช้งานได้อย่างสมบูรณ์ซึ่งแสดงการดำเนินงานของโซลูชันประเภทนี้ (และอื่นๆ) ให้ดู ตัวอย่าง: ทำงานกับโซลูชัน
สร้างผู้เผยแพร่
ทุกโซลูชันต้องมีผู้เผยแพร่ ซึ่งแสดงด้วย ผู้เผยแพร่เอนทิตี ผู้เผยแพร่ต้องการดังต่อไปนี้:
- คำนำหน้าการเลือกกำหนด
- ชื่อที่ไม่ซ้ำกัน
- ชื่อที่เรียกง่าย
หมายเหตุ
สำหรับแนวทาง ALM ที่ดีต่อสุขภาพ ให้ใช้ผู้เผยแพร่และโซลูชันที่กำหนดเองเสมอ ไม่ใช่โซลูชันและผู้เผยแพร่เริ่มต้น สำหรับการปรับใช้ของคุณ
ตัวอย่างรหัสต่อไปนี้กำหนดผู้เผยแพร่ก่อน และตรวจสอบเพื่อดูว่ามีผู้เผยแพร่อยู่แล้วหรือไม่ ตามชื่อเฉพาะ หากมีอยู่แล้ว คำนำหน้าการเลื่อกำหนดอาจต้องมีการเปลี่ยนแปลง ดังนั้นตัวอย่างนี้พยายามจับภาพคำนำหน้าการเลือกกำหนดปัจจุบัน PublisherId
ถูกจับภาพด้วย เพื่อให้สามารถลบเรกคอร์ดผู้เผยแพร่ได้ หากไม่พบผู้เผยแพร่ ผู้เผยแพร่รายใหม่จะถูกสร้างขึ้น โดยใช้วิธี IOrganizationService สร้าง
// Define a new publisher
Publisher _myPublisher = new Publisher
{
UniqueName = "contoso-publisher",
FriendlyName = "Contoso publisher",
SupportingWebsiteUrl =
"https://learn.microsoft.com/powerapps/developer/data-platform/overview",
CustomizationPrefix = "contoso",
EMailAddress = "someone@contoso.com",
Description = "This publisher was created from sample code"
};
// Does the publisher already exist?
QueryExpression querySamplePublisher = new QueryExpression
{
EntityName = Publisher.EntityLogicalName,
ColumnSet = new ColumnSet("publisherid", "customizationprefix"),
Criteria = new FilterExpression()
};
querySamplePublisher.Criteria.AddCondition("uniquename", ConditionOperator.Equal,
_myPublisher.UniqueName);
EntityCollection querySamplePublisherResults =
_serviceProxy.RetrieveMultiple(querySamplePublisher);
Publisher SamplePublisherResults = null;
// If the publisher already exists, use it
if (querySamplePublisherResults.Entities.Count > 0)
{
SamplePublisherResults = (Publisher)querySamplePublisherResults.Entities[0];
_publisherId = (Guid)SamplePublisherResults.PublisherId;
_customizationPrefix = SamplePublisherResults.CustomizationPrefix;
}
// If the publisher doesn't exist, create it
if (SamplePublisherResults == null)
{
_publisherId = _serviceProxy.Create(_myPublisher);
Console.WriteLine(String.Format("Created publisher: {0}.",
_myPublisher.FriendlyName));
_customizationPrefix = _myPublisher.CustomizationPrefix;
}
การสร้างโซลูชันที่ไม่มีการจัดการ
หลังจากคุณมีผู้เผยแพร่ที่กำหนดเองพร้อมใช้งานแล้ว คุณสามารถสร้างโซลูชันที่ไม่มีการจัดการได้ ตารางต่อไปนี้แสดงรายการฟิลด์พร้อมคำอธิบายที่โซลูชันประกอบด้วย
ป้ายสนาม | คำอธิบาย |
---|---|
ชื่อที่แสดง | ชื่อสำหรับโซลูชัน |
ชื่อ | Microsoft Dataverse สร้างชื่อที่ไม่ซ้ำกันตาม ชื่อที่แสดง คุณสามารถแก้ไขชื่อที่ไม่ซ้ำกันได้ ชื่อที่ไม่ซ้ำกันต้องมีเฉพาะตัวเลข ตัวอักษร และเครื่องหมายขีดล่างเท่านั้น |
ผู้เผยแพร่ | ใช้การค้นหา ผู้เผยแพร่ เพื่อเชื่อมโยงโซลูชันกับผู้เผยแพร่ |
รุ่น | ระบุรุ่นโดยใช้รูปแบบต่อไปนี้: major.minor.build.revision (ตัวอย่างเช่น 1.0.0.0 |
เพจการกำหนดค่า | หากคุณรวมทรัพยากรเว็บ HTML ในโซลูชันของคุณ คุณสามารถใช้การค้นหานี้เพื่อเพิ่มเป็นหน้าการกำหนดค่าโซลูชันที่กำหนดของคุณ |
รายละเอียด | ใช้ฟิลด์นี้เพื่อรวมรายละเอียดที่เกี่ยวข้องเกี่ยวกับโซลูชันของคุณ |
ด้านล่างคือตัวอย่างรหัสเพื่อสร้างโซลูชันที่ไม่ได้รับการจัดการ ซึ่งใช้ผู้เผยแพร่ที่เราสร้างในส่วนก่อนหน้า
// Create a solution
Solution solution = new Solution
{
UniqueName = "sample-solution",
FriendlyName = "Sample solution",
PublisherId = new EntityReference(Publisher.EntityLogicalName, _publisherId),
Description = "This solution was created by sample code.",
Version = "1.0"
};
// Check whether the solution already exists
QueryExpression queryCheckForSampleSolution = new QueryExpression
{
EntityName = Solution.EntityLogicalName,
ColumnSet = new ColumnSet(),
Criteria = new FilterExpression()
};
queryCheckForSampleSolution.Criteria.AddCondition("uniquename",
ConditionOperator.Equal, solution.UniqueName);
// Attempt to retrieve the solution
EntityCollection querySampleSolutionResults =
_serviceProxy.RetrieveMultiple(queryCheckForSampleSolution);
// Create the solution if it doesn't already exist
Solution SampleSolutionResults = null;
if (querySampleSolutionResults.Entities.Count > 0)
{
SampleSolutionResults = (Solution)querySampleSolutionResults.Entities[0];
_solutionsSampleSolutionId = (Guid)SampleSolutionResults.SolutionId;
}
if (SampleSolutionResults == null)
{
_solutionsSampleSolutionId = _serviceProxy.Create(solution);
}
หลังจากที่คุณสร้างโซลูชันที่ไม่มีการจัดการ คุณสามารถเพิ่มส่วนประกอบโซลูชันโดยสร้างในบริบทของโซลูชันนี้ หรือโดยการเพิ่มส่วนประกอบที่มีอยู่จากโซลูชันอื่นๆ ข้อมูลเพิ่มเติม: เพิ่มส่วนประกอบโซลูชันใหม่ และ เพิ่มส่วนประกอบโซลูชันที่มีอยู่
ส่งออกโซลูชันที่ไม่มีการจัดการ
ตัวอย่างโค้ดนี้แสดงวิธีส่งออกโซลูชันที่ไม่มีการจัดการหรือแพ็คเกจโซลูชันที่มีการจัดการ รหัสใช้คลาส ExportSolutionRequest เพื่อส่งออกไฟล์บีบอัดที่เป็นตัวแทนของโซลูชั่นที่ไม่มีการจัดการ ตัวเลือกในการสร้างโซลูชันที่มีการจัดการถูกตั้งค่าโดยใช้คุณสมบัติ การบริหารจัดการ ตัวอย่างนี้บันทึกไฟล์ชื่อ samplesolution.zip ไปยังโฟลเดอร์ผลลัพธ์
// Export a solution
ExportSolutionRequest exportSolutionRequest = new ExportSolutionRequest();
exportSolutionRequest.Managed = false;
exportSolutionRequest.SolutionName = solution.UniqueName;
ExportSolutionResponse exportSolutionResponse =
(ExportSolutionResponse)_serviceProxy.Execute(exportSolutionRequest);
byte[] exportXml = exportSolutionResponse.ExportSolutionFile;
string filename = solution.UniqueName + ".zip";
File.WriteAllBytes(outputDir + filename, exportXml);
Console.WriteLine("Solution exported to {0}.", outputDir + filename);
นำเข้าโซลูชันที่ไม่มีการจัดการ
การนำเข้า (หรืออัปเกรด) โซลูชันโดยใช้รหัสสามารถทำได้ด้วย ImportSolutionRequest
// Install or upgrade a solution
byte[] fileBytes = File.ReadAllBytes(ManagedSolutionLocation);
ImportSolutionRequest impSolReq = new ImportSolutionRequest()
{
CustomizationFile = fileBytes
};
_serviceProxy.Execute(impSolReq);
การติดตามการนำเข้าสำเร็จ
คุณสามารถใช้เอนทิตี ImportJob เพื่อรวบรวมข้อมูลเกี่ยวกับความสำเร็จของการนำเข้าโซลูชัน เมื่อคุณระบุ ImportJobId
สำหรับ ImportSolutionRequestคุณสามารถใช้ค่านั้นเพื่อสอบถามเอนทิตี ImportJob เกี่ยวกับสถานะของการนำเข้า ImportJobId
ยังสามารถใช้เพื่อดาวน์โหลดไฟล์บันทึกการนำเข้า โดยใช้ข้อความ RetrieveFormattedImportJobResultsRequest
// Monitor solution import success
byte[] fileBytesWithMonitoring = File.ReadAllBytes(ManagedSolutionLocation);
ImportSolutionRequest impSolReqWithMonitoring = new ImportSolutionRequest()
{
CustomizationFile = fileBytes,
ImportJobId = Guid.NewGuid()
};
_serviceProxy.Execute(impSolReqWithMonitoring);
ImportJob job = (ImportJob)_serviceProxy.Retrieve(ImportJob.EntityLogicalName,
impSolReqWithMonitoring.ImportJobId, new ColumnSet(new System.String[] { "data",
"solutionname" }));
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.LoadXml(job.Data);
String ImportedSolutionName =
doc.SelectSingleNode("//solutionManifest/UniqueName").InnerText;
String SolutionImportResult =
doc.SelectSingleNode("//solutionManifest/result/\@result").Value;
Console.WriteLine("Report from the ImportJob data");
Console.WriteLine("Solution Unique name: {0}", ImportedSolutionName);
Console.WriteLine("Solution Import Result: {0}", SolutionImportResult);
Console.WriteLine("");
// This code displays the results for Global Option sets installed as part of a
// solution.
System.Xml.XmlNodeList optionSets = doc.SelectNodes("//optionSets/optionSet");
foreach (System.Xml.XmlNode node in optionSets)
{
string OptionSetName = node.Attributes["LocalizedName"].Value;
string result = node.FirstChild.Attributes["result"].Value;
if (result == "success")
{
Console.WriteLine("{0} result: {1}",OptionSetName, result);
}
else
{
string errorCode = node.FirstChild.Attributes["errorcode"].Value;
string errorText = node.FirstChild.Attributes["errortext"].Value;
Console.WriteLine("{0} result: {1} Code: {2} Description: {3}",OptionSetName,
result, errorCode, errorText);
}
}
เนื้อหาของคุณสมบัติ Data
เป็นสตริงที่แทนไฟล์ XML ของโซลูชัน
เพิ่มและเอาส่วนประกอบของโซลูชันออก
เรียนรู้วิธีเพิ่มและลบส่วนประกอบของโซลูชันโดยใช้รหัส
เพิ่มส่วนประกอบของโซลูชันใหม่
ตัวอย่างนี้แสดงวิธีการสร้างส่วนประกอบของโซลูชันที่เกี่ยวข้องกับโซลูชันเฉพาะ หากคุณไม่ได้เชื่อมโยงส่วนประกอบของโซลูชันกับโซลูชันเฉพาะ เมื่อมีการสร้างขึ้น จะมีการเพิ่มไปยังโซลูชันเริ่มต้นเท่านั้น และคุณจะต้องเพิ่มส่วนประกอบนั้นลงในโซลูชันด้วยตนเองหรือโดยใช้รหัสที่รวมอยู่ใน เพิ่มส่วนประกอบของโซลูชันที่มีอยู่
รหัสนี้สร้างชุดตัวเลือกส่วนกลางใหม่ และเพิ่มลงในโซลูชันที่มีชื่อเฉพาะเท่ากับ _primarySolutionName
OptionSetMetadata optionSetMetadata = new OptionSetMetadata()
{
Name = _globalOptionSetName,
DisplayName = new Label("Example Option Set", _languageCode),
IsGlobal = true,
OptionSetType = OptionSetType.Picklist,
Options =
{
new OptionMetadata(new Label("Option 1", _languageCode), 1),
new OptionMetadata(new Label("Option 2", _languageCode), 2)
}
};
CreateOptionSetRequest createOptionSetRequest = new CreateOptionSetRequest
{
OptionSet = optionSetMetadata
};
createOptionSetRequest.SolutionUniqueName = _primarySolutionName;
_serviceProxy.Execute(createOptionSetRequest);
เพิ่มส่วนประกอบของโซลูชันที่มีอยู่
ตัวอย่างนี้แสดงวิธีการเพิ่มส่วนประกอบของโซลูชันที่มีอยู่ลงในโซลูชัน
รหัสต่อไปนี้ใช้ AddSolutionComponentRequest เพื่อเพิ่มเอนทิตี Account
เป็นส่วนประกอบของโซลูชันไปยังโซลูชันที่ไม่มีการจัดการ
// Add an existing Solution Component
// Add the Account entity to the solution
RetrieveEntityRequest retrieveForAddAccountRequest = new RetrieveEntityRequest()
{
LogicalName = Account.EntityLogicalName
};
RetrieveEntityResponse retrieveForAddAccountResponse = (RetrieveEntityResponse)_serviceProxy.Execute(retrieveForAddAccountRequest);
AddSolutionComponentRequest addReq = new AddSolutionComponentRequest()
{
ComponentType = (int)componenttype.Entity,
ComponentId = (Guid)retrieveForAddAccountResponse.EntityMetadata.MetadataId,
SolutionUniqueName = solution.UniqueName
};
_serviceProxy.Execute(addReq);
เอาส่วนประกอบของโซลูชันออก
ตัวอย่างนี้แสดงวิธีการลบส่วนประกอบของโซลูชันออกจากโซลูชันที่ไม่มีการจัดการ รหัสต่อไปนี้ใช้ RemoveSolutionComponentRequest เพื่อลบส่วนประกอบของโซลูชันของเอนทิตีออกจากโซลูชันที่ไม่มีการจัดการ solution.UniqueName
อ้างอิงโซลูชันที่สร้างขึ้นใน สร้างโซลูชันที่ไม่มีการจัดการ
// Remove a Solution Component
// Remove the Account entity from the solution
RetrieveEntityRequest retrieveForRemoveAccountRequest = new RetrieveEntityRequest()
{
LogicalName = Account.EntityLogicalName
};
RetrieveEntityResponse retrieveForRemoveAccountResponse = (RetrieveEntityResponse)_serviceProxy.Execute(retrieveForRemoveAccountRequest);
RemoveSolutionComponentRequest removeReq = new RemoveSolutionComponentRequest()
{
ComponentId = (Guid)retrieveForRemoveAccountResponse.EntityMetadata.MetadataId,
ComponentType = (int)componenttype.Entity,
SolutionUniqueName = solution.UniqueName
};
_serviceProxy.Execute(removeReq);
การลบโซลูชัน
ตัวอย่างต่อไปนี้แสดงวิธีการดึงโซลูชันโดยใช้โซลูชัน uniquename
แล้วจากนั้น แยก solutionid
จากผลลัพธ์ จากนั้น ตัวอย่างจะใช้ไฟล์ solutionid
กับIOrganizationService Delete วิธีการลบโซลูชัน
// Delete a solution
QueryExpression queryImportedSolution = new QueryExpression
{
EntityName = Solution.EntityLogicalName,
ColumnSet = new ColumnSet(new string[] { "solutionid", "friendlyname" }),
Criteria = new FilterExpression()
};
queryImportedSolution.Criteria.AddCondition("uniquename", ConditionOperator.Equal, ImportedSolutionName);
Solution ImportedSolution = (Solution)_serviceProxy.RetrieveMultiple(queryImportedSolution).Entities[0];
_serviceProxy.Delete(Solution.EntityLogicalName, (Guid)ImportedSolution.SolutionId);
Console.WriteLine("Deleted the {0} solution.", ImportedSolution.FriendlyName);
การโคลน การแก้ไข และการอัปเกรด
คุณสามารถดำเนินการโซลูชันเพิ่มเติมได้โดยใช้ API ที่มีอยู่ สำหรับโซลูชันการลอกแบบและการแก้ไข ให้ใช้ CloneAsPatchRequest และ CloneAsSolutionRequest สำหรับข้อมูลเกี่ยวกับการโคลนและการแก้ไข ให้ดู สร้างการแก้ไขโซลูชัน
เมื่อดำเนินการอัพเกรดโซลูชัน ให้ใช้ StageAndUpgradeRequest และ DeleteAndPromoteRequest สำหรับข้อมูลเพิ่มเติมเกี่ยวกับกระบวนการจัดเตรียมและอัพเกรด โปรดดู อัปเกรดหรือปรับปรุงโซลูชัน
ตรวจพบการขึ้นต่อกันของโซลูชัน
ตัวอย่างนี้แสดงวิธีการสร้างรายงานที่แสดงการพึ่งพาระหว่างส่วนประกอบของโซลูชัน
รหัสนี้จะ:
ดึงส่วนประกอบทั้งหมดสำหรับโซลูชัน
ดึงข้อมูลการอ้างอิงทั้งหมดสำหรับส่วนประกอบแต่ละรายการ
สำหรับการขึ้นต่อกันแต่ละรายการที่พบ จะแสดงรายงานที่อธิบายการขึ้นต่อกัน
// Grab all Solution Components for a solution.
QueryByAttribute componentQuery = new QueryByAttribute
{
EntityName = SolutionComponent.EntityLogicalName,
ColumnSet = new ColumnSet("componenttype", "objectid", "solutioncomponentid", "solutionid"),
Attributes = { "solutionid" },
// In your code, this value would probably come from another query.
Values = { _primarySolutionId }
};
IEnumerable<SolutionComponent> allComponents =
_serviceProxy.RetrieveMultiple(componentQuery).Entities.Cast<SolutionComponent>();
foreach (SolutionComponent component in allComponents)
{
// For each solution component, retrieve all dependencies for the component.
RetrieveDependentComponentsRequest dependentComponentsRequest =
new RetrieveDependentComponentsRequest
{
ComponentType = component.ComponentType.Value,
ObjectId = component.ObjectId.Value
};
RetrieveDependentComponentsResponse dependentComponentsResponse =
(RetrieveDependentComponentsResponse)_serviceProxy.Execute(dependentComponentsRequest);
// If there are no dependent components, we can ignore this component.
if (dependentComponentsResponse.EntityCollection.Entities.Any() == false)
continue;
// If there are dependencies upon this solution component, and the solution
// itself is managed, then you will be unable to delete the solution.
Console.WriteLine("Found {0} dependencies for Component {1} of type {2}",
dependentComponentsResponse.EntityCollection.Entities.Count,
component.ObjectId.Value,
component.ComponentType.Value
);
//A more complete report requires more code
foreach (Dependency d in dependentComponentsResponse.EntityCollection.Entities)
{
DependencyReport(d);
}
}
วิธีการ DependencyReport
อยู่ในตัวอย่างรหัสต่อไปนี้
รายงานการขึ้นต่อกัน
วิธีการ DependencyReport
ให้ข้อความเป็นมิตรมากขึ้นโดยขึ้นอยู่กับข้อมูลที่พบภายในการขึ้นต่อกัน
หมายเหตุ
ในตัวอย่างนี้ มีการใช้วิธีการเพียงบางส่วนเท่านั้น ซึ่งสามารถแสดงข้อความเฉพาะสำหรับส่วนประกอบแอตทริบิวต์และโซลูชันของชุดตัวเลือก
/// <summary>
/// Shows how to get a more friendly message based on information within the dependency
/// <param name="dependency">A Dependency returned from the RetrieveDependentComponents message</param>
/// </summary>
public void DependencyReport(Dependency dependency)
{
// These strings represent parameters for the message.
String dependentComponentName = "";
String dependentComponentTypeName = "";
String dependentComponentSolutionName = "";
String requiredComponentName = "";
String requiredComponentTypeName = "";
String requiredComponentSolutionName = "";
// The ComponentType global Option Set contains options for each possible component.
RetrieveOptionSetRequest componentTypeRequest = new RetrieveOptionSetRequest
{
Name = "componenttype"
};
RetrieveOptionSetResponse componentTypeResponse = (RetrieveOptionSetResponse)_serviceProxy.Execute(componentTypeRequest);
OptionSetMetadata componentTypeOptionSet = (OptionSetMetadata)componentTypeResponse.OptionSetMetadata;
// Match the Component type with the option value and get the label value of the option.
foreach (OptionMetadata opt in componentTypeOptionSet.Options)
{
if (dependency.DependentComponentType.Value == opt.Value)
{
dependentComponentTypeName = opt.Label.UserLocalizedLabel.Label;
}
if (dependency.RequiredComponentType.Value == opt.Value)
{
requiredComponentTypeName = opt.Label.UserLocalizedLabel.Label;
}
}
// The name or display name of the component is retrieved in different ways depending on the component type
dependentComponentName = getComponentName(dependency.DependentComponentType.Value, (Guid)dependency.DependentComponentObjectId);
requiredComponentName = getComponentName(dependency.RequiredComponentType.Value, (Guid)dependency.RequiredComponentObjectId);
// Retrieve the friendly name for the dependent solution.
Solution dependentSolution = (Solution)_serviceProxy.Retrieve
(
Solution.EntityLogicalName,
(Guid)dependency.DependentComponentBaseSolutionId,
new ColumnSet("friendlyname")
);
dependentComponentSolutionName = dependentSolution.FriendlyName;
// Retrieve the friendly name for the required solution.
Solution requiredSolution = (Solution)_serviceProxy.Retrieve
(
Solution.EntityLogicalName,
(Guid)dependency.RequiredComponentBaseSolutionId,
new ColumnSet("friendlyname")
);
requiredComponentSolutionName = requiredSolution.FriendlyName;
// Display the message
Console.WriteLine("The {0} {1} in the {2} depends on the {3} {4} in the {5} solution.",
dependentComponentName,
dependentComponentTypeName,
dependentComponentSolutionName,
requiredComponentName,
requiredComponentTypeName,
requiredComponentSolutionName);
}
ตรวจหาว่าอาจมีการลบส่วนประกอบของโซลูชันหรือไม่
ใช้ข้อความ RetrieveDependenciesForDeleteRequest เพื่อระบุส่วนประกอบของโซลูชันอื่นใดๆ ที่จะป้องกันไม่ให้ส่วนประกอบของโซลูชันที่ระบุถูกลบ ตัวอย่างรหัสต่อไปนี้ค้นหาแอตทริบิวต์โดยใช้ชุดตัวเลือกส่วนกลางที่รู้จัก แอ็ตทริบิวต์ใดๆ ที่ใช้ชุดตัวเลือกส่วนกลางจะป้องกันไม่ให้ชุดตัวเลือกส่วนกลางถูกลบ
// Use the RetrieveOptionSetRequest message to retrieve
// a global option set by it's name.
RetrieveOptionSetRequest retrieveOptionSetRequest =
new RetrieveOptionSetRequest
{
Name = _globalOptionSetName
};
// Execute the request.
RetrieveOptionSetResponse retrieveOptionSetResponse =
(RetrieveOptionSetResponse)_serviceProxy.Execute(
retrieveOptionSetRequest);
_globalOptionSetId = retrieveOptionSetResponse.OptionSetMetadata.MetadataId;
if (_globalOptionSetId != null)
{
// Use the global OptionSet MetadataId with the appropriate componenttype
// to call RetrieveDependenciesForDeleteRequest
RetrieveDependenciesForDeleteRequest retrieveDependenciesForDeleteRequest = new RetrieveDependenciesForDeleteRequest
{
ComponentType = (int)componenttype.OptionSet,
ObjectId = (Guid)_globalOptionSetId
};
RetrieveDependenciesForDeleteResponse retrieveDependenciesForDeleteResponse =
(RetrieveDependenciesForDeleteResponse)_serviceProxy.Execute(retrieveDependenciesForDeleteRequest);
Console.WriteLine("");
foreach (Dependency d in retrieveDependenciesForDeleteResponse.EntityCollection.Entities)
{
if (d.DependentComponentType.Value == 2)//Just testing for Attributes
{
String attributeLabel = "";
RetrieveAttributeRequest retrieveAttributeRequest = new RetrieveAttributeRequest
{
MetadataId = (Guid)d.DependentComponentObjectId
};
RetrieveAttributeResponse retrieveAttributeResponse = (RetrieveAttributeResponse)_serviceProxy.Execute(retrieveAttributeRequest);
AttributeMetadata attmet = retrieveAttributeResponse.AttributeMetadata;
attributeLabel = attmet.DisplayName.UserLocalizedLabel.Label;
Console.WriteLine("An {0} named {1} will prevent deleting the {2} global option set.",
(componenttype)d.DependentComponentType.Value,
attributeLabel,
_globalOptionSetName);
}
}
}