Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Өндірістің өмірлік циклін дамытудың бөлігі ретінде белгілі бір тапсырмаларды орындау үшін теңшелетін автоматтандыруды жасағыңыз келуі мүмкін. Мысалы, DevOps жобасының үдерістер тізбегінде сынақ ортасын жасайтын, басқарылмайтын шешімді импорттайтын, басқарылмайтын шешімді басқарылатын шешім ретінде экспорттайтын және соңында ортаны жоятын кейбір реттелетін кодты немесе сценарийді орындағыңыз келуі мүмкін. Осы әрекеттерді және т.б. әрекеттерді сізге қолжетімді API интерфейстерін пайдалану арқылы орындауға болады. Мұнда .NET Dataverse және теңшелетін код үшін SDK көмегімен қол жеткізуге болатын кейбір мысалдар берілген.
Ескертпе
Сондай-ақ, осы бірдей әрекеттерді Web API интерфейсінің көмегімен орындауға болады. Қатысты әрекеттер: ImportSolution, ExportSolution, CloneAsPatch және CloneAsSolution.
Осы мақаладағы код үлгілері CrmSvcUtil немесе PAC CLI көмегімен жасалған ерте байланыстырылған нысан түрлерін пайдаланады. Қосымша ақпарат: .NET үшін SDK көмегімен кешіктірілген және ерте байланыстырылған бағдарламалау
Басқарылмайтын шешімді жасау, экспорттау немесе импорттау
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);
Тек қосқыңыз келетін компоненттің дұрыс ComponentType бүтін сан мәнін білсеңіз ғана қолданыңызAddSolutionComponentRequest. Көптеген кең таралған компонент түрлері SolutionComponent.ComponentType таңдау бағанында қолданылатын жаһандық таңдауда анықталадыcomponenttype, бірақ кейбір жаңа компонент түрлері онда көрсетілмеуі мүмкін. Мүмкін болған жағдайда, компонентті мақсатты шешім контекстінде қасиет SolutionUniqueName немесе SolutionUniqueName қосымша параметр арқылы жасап немесе жаңартыңыз. Қосымша ақпарат: Шешім компонентін шешімге қосымша параметр арқылы байланыстыру.
Шешім құрамдасын алып тастау
Бұл үлгі шешім құрамдасын басқарылмайтын шешімнен алып тастау жолын көрсетеді. Келесі код басқарылмайтын шешімнен кесте шешімінің құрамдас бөлігін жою үшін 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);
}
}
}