> ## Documentation Index
> Fetch the complete documentation index at: https://docs.superoffice.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Creating a dynamic selection (services)

> Creating a dynamic selection using NetServer services

As the word implies, a dynamic selection is **a selection that is bound to change dynamically** and it's **based on search criteria** and not just static members.

A typical criterion would be "Add all contacts with a specific business type". This would cause the member count of this selection to increase each time a new contact is added to the database that matches the business type specified as a search criterion for this selection. You may have as many search criteria as you want.

## Add restrictions to the selection

```csharp CS theme={null}
using SuperOffice;
using SuperOffice.CRM.Services;
using SuperOffice.CRM.ArchiveLists;
using SuperOffice.CRM.Globalization;
using SuperOffice.Util;

using(SoSession mySession = SoSession.Authenticate("sam", "sam"))
{
  //Initializing the FindAgent
  using(FindAgent newFindAgt = new FindAgent())
  {
    //Declaration of the Local variable
    string storageType = "Criteria";
    string providerName = "ContactDynamicSelection";
    string storageKey = "selection=61";
    string[] staticColumns = new string[] { "name", "contactId" };

    //Making use of a method exposed in the FindAgent
    //GetAvailableRestrictionColumns - which Gets a list of
    //the column names corresponding to available restrictions for
    //a certain archive provider and restriction storage provider.
    string[] handledColumns = newFindAgt.GetAvailableRestrictionColumns(storageType, providerName);

    //GetSpecifiedCriteriaInformationWithDefaults - Get criteria information from a
    //set of saved criteria, for a specific set of columns.
    CriteriaInformation criteria = newFindAgt.GetSpecifiedCriteriaInformationWithDefaults(storageType, providerName, storageKey, handledColumns, staticColumns);

    //Represents a list of keys and values i.e columns and the conditions.
    Dictionary<string, ArchiveRestrictionInfo> restrictions = ArchiveRestrictionInfo.ToNameDictionary(criteria.Restrictions);

    //Setting the restriction for specific columns
    //Udef fields may not run depending on the database.
    //string values
    //Restriction 1
    restrictions["associateId"].SetValue("103");
    restrictions["associateId"].IsActive = true;

    //Restriction 2
    restrictions["name"].SetValue("est");
    restrictions["name"].Operator = "contains";
    restrictions["name"].IsActive = true;

    //Save the restrictions so that it may be used later as search criteria
    newFindAgt.SaveRestrictions(storageType, providerName, storageKey, CollectionOps.DictionaryValuesToArray(restrictions));
  }
}
```

### Initialize and declare the variables

The first few lines of the codes initialize and declare the variables that we plan to use in the code.

<Tip>
  If you are new to selections, check out [how to use criteria in selection searches][1].
</Tip>

* **storageType** - we use the *Criteria* type since this is a selection

* **providerName** - we use `ContactDynamicSelection` since we plan to create a dynamic selection

* **storageKey** - we use `selection=61` since this will allow us to create a restriction for that particular selection ID. In the statement, `selection` is the name of the table and 61 is the primary key ID (selection\_id).

* **staticColumns** - we use `name` and `contactId`

* **handledColumns** - retrieved based on `storageType` and `providerName`

```csharp CS theme={null}
using SuperOffice;
using SuperOffice.CRM.Services;
using SuperOffice.CRM.ArchiveLists;
using SuperOffice.CRM.Globalization;
using SuperOffice.Util;

using(SoSession mySession = SoSession.Authenticate("sam", "sam"))
{
  //Initializing the FindAgent
  using(FindAgent newFindAgt = new FindAgent())
  {
    //Declaration of the Local variable
    string storageType = "Criteria";
    string providerName = "ContactDynamicSelection";
    string storageKey = "selection=61";
    string[] staticColumns = new string[] { "name", "contactId" };

    //Making use of a method exposed in the FindAgent
    //GetAvailableRestrictionColumns - which Gets a list of
    //the column names corresponding to available restrictions for
    //a certain archive provider and restriction storage provider.
    string[] handledColumns = newFindAgt.GetAvailableRestrictionColumns(storageType, providerName);

    //GetSpecifiedCriteriaInformationWithDefaults - Get criteria information from a
    //set of saved criteria, for a specific set of columns.
    CriteriaInformation criteria = newFindAgt.GetSpecifiedCriteriaInformationWithDefaults(storageType, providerName, storageKey, handledColumns, staticColumns);

    //Represents a list of keys and values i.e columns and the conditions.
    Dictionary<string, ArchiveRestrictionInfo> restrictions = ArchiveRestrictionInfo.ToNameDictionary(criteria.Restrictions);

    //Setting the restriction for specific columns
    //Udef fields may not run depending on the database.
    //string values
    //Restriction 1
    restrictions["associateId"].SetValue("103");
    restrictions["associateId"].IsActive = true;

    //Restriction 2
    restrictions["name"].SetValue("est");
    restrictions["name"].Operator = "contains";
    restrictions["name"].IsActive = true;

    //Save the restrictions so that it may be used later as search criteria
    newFindAgt.SaveRestrictions(storageType, providerName, storageKey, CollectionOps.DictionaryValuesToArray(restrictions));
  }
}
```

### GetSpecifiedCriteriaInformationWithDefaults

```csharp CS theme={null}
using SuperOffice;
using SuperOffice.CRM.Services;
using SuperOffice.CRM.ArchiveLists;
using SuperOffice.CRM.Globalization;
using SuperOffice.Util;

using(SoSession mySession = SoSession.Authenticate("sam", "sam"))
{
  //Initializing the FindAgent
  using(FindAgent newFindAgt = new FindAgent())
  {
    //Declaration of the Local variable
    string storageType = "Criteria";
    string providerName = "ContactDynamicSelection";
    string storageKey = "selection=61";
    string[] staticColumns = new string[] { "name", "contactId" };

    //Making use of a method exposed in the FindAgent
    //GetAvailableRestrictionColumns - which Gets a list of
    //the column names corresponding to available restrictions for
    //a certain archive provider and restriction storage provider.
    string[] handledColumns = newFindAgt.GetAvailableRestrictionColumns(storageType, providerName);

    //GetSpecifiedCriteriaInformationWithDefaults - Get criteria information from a
    //set of saved criteria, for a specific set of columns.
    CriteriaInformation criteria = newFindAgt.GetSpecifiedCriteriaInformationWithDefaults(storageType, providerName, storageKey, handledColumns, staticColumns);

    //Represents a list of keys and values i.e columns and the conditions.
    Dictionary<string, ArchiveRestrictionInfo> restrictions = ArchiveRestrictionInfo.ToNameDictionary(criteria.Restrictions);

    //Setting the restriction for specific columns
    //Udef fields may not run depending on the database.
    //string values
    //Restriction 1
    restrictions["associateId"].SetValue("103");
    restrictions["associateId"].IsActive = true;

    //Restriction 2
    restrictions["name"].SetValue("est");
    restrictions["name"].Operator = "contains";
    restrictions["name"].IsActive = true;

    //Save the restrictions so that it may be used later as search criteria
    newFindAgt.SaveRestrictions(storageType, providerName, storageKey, CollectionOps.DictionaryValuesToArray(restrictions));
  }
}
```

With the execution of the above code, we have retrieved criteria information from a set of saved criteria, for specific set columns. In the case of the example, this would be empty.

### Create variable to store restrictions

The next step is to create a variable that could be used to store the restrictions.

```csharp CS theme={null}
using SuperOffice;
using SuperOffice.CRM.Services;
using SuperOffice.CRM.ArchiveLists;
using SuperOffice.CRM.Globalization;
using SuperOffice.Util;

using(SoSession mySession = SoSession.Authenticate("sam", "sam"))
{
  //Initializing the FindAgent
  using(FindAgent newFindAgt = new FindAgent())
  {
    //Declaration of the Local variable
    string storageType = "Criteria";
    string providerName = "ContactDynamicSelection";
    string storageKey = "selection=61";
    string[] staticColumns = new string[] { "name", "contactId" };

    //Making use of a method exposed in the FindAgent
    //GetAvailableRestrictionColumns - which Gets a list of
    //the column names corresponding to available restrictions for
    //a certain archive provider and restriction storage provider.
    string[] handledColumns = newFindAgt.GetAvailableRestrictionColumns(storageType, providerName);

    //GetSpecifiedCriteriaInformationWithDefaults - Get criteria information from a
    //set of saved criteria, for a specific set of columns.
    CriteriaInformation criteria = newFindAgt.GetSpecifiedCriteriaInformationWithDefaults(storageType, providerName, storageKey, handledColumns, staticColumns);

    //Represents a list of keys and values i.e columns and the conditions.
    Dictionary<string, ArchiveRestrictionInfo> restrictions = ArchiveRestrictionInfo.ToNameDictionary(criteria.Restrictions);

    //Setting the restriction for specific columns
    //Udef fields may not run depending on the database.
    //string values
    //Restriction 1
    restrictions["associateId"].SetValue("103");
    restrictions["associateId"].IsActive = true;

    //Restriction 2
    restrictions["name"].SetValue("est");
    restrictions["name"].Operator = "contains";
    restrictions["name"].IsActive = true;

    //Save the restrictions so that it may be used later as search criteria
    newFindAgt.SaveRestrictions(storageType, providerName, storageKey, CollectionOps.DictionaryValuesToArray(restrictions));
  }
}
```

The `Dictionary` class from the `System.Collection.Generic` namespace is used to store the restriction as a key-value pair. The key is the name of the field the restriction is on, and the value is the `ArchiveRestrictionInfo` object that describes the restriction itself.

Once this is done we may add the necessary restrictions as shown below.

```csharp CS theme={null}
restrictions["associateId"].SetValue("103");
restrictions["associateId"].IsActive = true;
restrictions["name"].SetValue("est");
restrictions["name"].Operator = "contains";
restrictions["name"].IsActive = true;
```

### Save

Once all the required restrictions have been added the created restriction can be saved by executing the following statement.

```csharp CS theme={null}
using SuperOffice;
using SuperOffice.CRM.Services;
using SuperOffice.CRM.ArchiveLists;
using SuperOffice.CRM.Globalization;
using SuperOffice.Util;

using(SoSession mySession = SoSession.Authenticate("sam", "sam"))
{
  //Initializing the FindAgent
  using(FindAgent newFindAgt = new FindAgent())
  {
    //Declaration of the Local variable
    string storageType = "Criteria";
    string providerName = "ContactDynamicSelection";
    string storageKey = "selection=61";
    string[] staticColumns = new string[] { "name", "contactId" };

    //Making use of a method exposed in the FindAgent
    //GetAvailableRestrictionColumns - which Gets a list of
    //the column names corresponding to available restrictions for
    //a certain archive provider and restriction storage provider.
    string[] handledColumns = newFindAgt.GetAvailableRestrictionColumns(storageType, providerName);

    //GetSpecifiedCriteriaInformationWithDefaults - Get criteria information from a
    //set of saved criteria, for a specific set of columns.
    CriteriaInformation criteria = newFindAgt.GetSpecifiedCriteriaInformationWithDefaults(storageType, providerName, storageKey, handledColumns, staticColumns);

    //Represents a list of keys and values i.e columns and the conditions.
    Dictionary<string, ArchiveRestrictionInfo> restrictions = ArchiveRestrictionInfo.ToNameDictionary(criteria.Restrictions);

    //Setting the restriction for specific columns
    //Udef fields may not run depending on the database.
    //string values
    //Restriction 1
    restrictions["associateId"].SetValue("103");
    restrictions["associateId"].IsActive = true;

    //Restriction 2
    restrictions["name"].SetValue("est");
    restrictions["name"].Operator = "contains";
    restrictions["name"].IsActive = true;

    //Save the restrictions so that it may be used later as search criteria
    newFindAgt.SaveRestrictions(storageType, providerName, storageKey, CollectionOps.DictionaryValuesToArray(restrictions));
  }
}
```

<Note>
  Though we have added only 2 restrictions explicitly, it can be seen that there are many conditions. This is because we have got the criteria with the `GetSpecifiedCriteriaInformationWithDefaults` method, which returns all criteria with default values. However, this would not be affecting the outcome of the selection since the other criteria are not active - they have no values to search for.
</Note>

## View the result with SelectionAgent or ArchiveAgent

We may also be able to view the results of the restriction with the `SelectionAgent` or the `ArchiveAgent`.

The following code shows how we can use the `SelectionAgent` to retrieve information about the particular selection.

```csharp theme={null}
using SuperOffice;
using SuperOffice.CRM.Services;

using(SoSession newSession = SoSession.Authenticate("sam", "sam"))
{
  using(SelectionAgent newSelAgt = new SelectionAgent())
  {
    SelectionEntity newSelEnt = newSelAgt.GetSelectionEntity(56);

    string entName = newSelEnt.Name;
    uint entMemCnt = newSelEnt.MemberCount;
  }
}
```

If we wish to retrieve the details of the members in the selection we need to use the `ArchiveAgent`. After authenticating, set the parameters like below.

```csharp CS theme={null}
  string archiveProviderName = SelectionProvider.ProviderName;
  string[] archiveColumns = new string[] { "contactId", "name", "selectionId" };
  ArchiveOrderByInfo[] archiveSrtOrd = new ArchiveOrderByInfo[1];
  archiveSrtOrd[0] = new ArchiveOrderByInfo("contactId", SuperOffice.Util.OrderBySortType.DESC);
  ArchiveRestrictionInfo[] archiveRest = new ArchiveRestrictionInfo[1];
  archiveRest[0] = new ArchiveRestrictionInfo("selectionId", "=", "61");
  string[] desiredEntities = { "staticContact", "staticPerson", "dynamicContact" };
  int page = 1;
  int pageSize = 10;
```

Then call `GetArchiveListByColumns()` and follow the patten for [getting selection members][2].

**Output:**

```text theme={null}
contactId   name        selectionId
125 Tester 1        61
126 Tester 2        61
127 Tester 3        61
128 Tester 4        61
129 Tester 5        61
```

[1]: ../../ifindagent/using-criteria

[2]: ./get-selection-members-services


## Related topics

- [Creating a dynamic selection using entities](/en/api/search/selection/entity/create-dynamic-entity.md)
- [Selection](/en/search-options/selection/learn/index.md)
- [Creating a selection](/en/api/search/selection/sql/add-person-to-selection.md)
- [Dynamic selections](/en/api/search/selection/dynamic-selections.md)
- [Display selection as a chart](/en/search-options/selection/learn/howto/display-as-charts.md)
- [Create selections](/en/search-options/selection/learn/create.md)
