D365 Collection Classes

Share this:

In Microsoft Dynamics 365 for Finance and Operations, there are several ways to store a collection of values, known as D365 collection classes. Quite often, developers will insert values into tables that have different field names and can each have their own data type. Each record is saved to the database for reading later. With D365 collection classes, developers store lists of primitive or complex data types in memory for use in a process. There are several different types of collection classes, each with its own benefits depending on the circumstances. I want to thank Tim Fluharty, whom I have learned a great deal from, and who provided a lot of information for this series of articles.

Types of Collection Classes

As an overview, there are five different types of D365 collection classes defined in the base Microsoft code. To explain, these special types of classes provide additional functionality that helps developers. They help store, find, and iterate through lists of objects. They each work a little bit differently.

  • Array – The Array class must hold values of the same data type. They are often used to hold multiple objects or records.
  • List – Used to store sequential values, which are all of the same data type. There are methods to make it easy to add values at the beginning or the end of the list.
  • Set – Every value added to a set must be of the same data type. However, values are not stored in the order in which you add them. Instead, they are optimized for checking if the same value already exists in the set. If you try to add a value that already exists, the duplicate value will not be added. This class is great when you are working with a unique set of values.
  • Map – Used to store a unique key and an associated value. Similar to a Dictionary in C#. All keys must have the same data type. Additionally, all values must have the same data type.
  • Struct – Similar to a class, these objects store multiple values relating to a specific entity together. For example, you might store a customer’s name, birthday, and address as a single item. A struct uses string indexes. A container, which is similar, uses numeric indexes.

To learn more, click on the above links for a detailed explanation of each D365 collection class. (Coming soon!)

Use Cases

Without going into specific detail (click on the links for those), there are several general use cases for D365 collection classes.

First, Lists are very useful when you need to add items at the beginning or end of a list, or combine lists.

Second, when looping through records, you can use a Set to keep track of a unique list of records you have already processed, so that you don’t process the same record twice. This is very helpful when a one-to-one join or a group by is not possible in the loop.

Third, Maps are helpful when you have a unique key, such as a customer ID, and several other values that you need to associate with that value. Later, use the unique key to quickly look up all values associated with that key. I’ve seen developers store several related values in comma-separated values. While it may be necessary with integrations, using D365 collection classes to store values is easier and safer.

Fourth, Structs help create a lightweight object or record without creating a separate class. Though, personally, I have to say I typically just create a new class.

To summarize, D365 collection classes are very helpful in the right scenario. They are used throughout the base Microsoft code. For instance, in inventory closing, indirect cost calculation, production variance, master planning, and BOM calculation.

Example Code

To explain just a little bit, see the example code using these D365 collection classes below. For more detail, click the links on each class type.

var notificationActions = new Array(Types::Class);

var notificationAction = new SystemNotificationActionDataContract();
notificationAction.Message("@ApplicationFoundation:GoToBatchJob");
notificationAction.Type(SystemNotificationActionType::AxDisplayMenuFunction);
notificationActions.value(1, notificationAction);

notificationAction = new SystemNotificationActionDataContract();
notificationAction.Message("@ApplicationFoundation:ManageBatchJobAlert");
notificationAction.Type(SystemNotificationActionType::AxDisplayMenuFunction);
notificationActions.value(2, notificationAction);

//Used to store sequential values, which are all of the same data type. 
//There are methods to make it easy to add values at the beginning or the end of the list.
List list = new List(Types::Integer);

// Add some elements into the list.
list.addStart(1);
list.addStart(2);
list.addStart(3);

//Every value added to a set must be of the same data type. 
//However, values are not stored in the order in which you add them. 
//Instead, they are optimized for checking if the same value already exists in the set. 
//If you try to add a value that already exists, the duplicate value will not be added.
Set set = new Set(Types::String);

//Add numbers to the set.
set.add("A");
set.add("B");
set.add("C");

//Used to store a unique key and an associated value. 
//Similar to a Dictionary in C#. All keys must have the same data type. 
//Additionally, all values must have the same data type.
Map map = new Map(Types::String, Types::Real);

//Add key-value pairs to the map.
map.insert("SO-123", 123.45);
map.insert("SO-789", 789.01);

//Similar to a class, these objects store multiple values relating to a specific entity together. 
//For example, you might store a customer's name, birthday, and address as a single item. 
//A struct uses string indexes. A container, which is similar, uses numeric indexes.
Struct struct;
SalesTable salesTable;

struct = new Struct(
    Types::String, "SalesId",
    Types::Real, "OrderTotal",
    Types::Record, "SalesTable");

struct.value("SalesId", "SO-123");
struct.value("OrderTotal", 17.56);

select firstOnly salesTable
    where salesTable.SalesId == "SO-123";
struct.value("SalesTable", salesTable);

Temp Tables

Significantly, you could create a temporary table, add fields, insert values, and then loop through the temporary table. However, there are a couple of reasons why using one of the collection classes is better.

Note: To create a temp table, simply create a normal table in the Application Explorer. Then, set the Table Type property to ‘Temporary‘. Now, records inserted into the table will not be written to the database. Instead, the values will be stored in memory in the table buffer variable. They will only exist as long as the table buffer is in scope.

First, to use a temporary table, you must create a new object in the Application Explorer. While there is nothing inherently wrong with this, it does expand the scope of when that object could be used. If you make changes in the future, be careful not to break any other logic that uses the temporary table.

Second, when using a temp table, you won’t have the base Microsoft methods that are available on D365 collection classes. Use the existing base logic to make specific use cases a lot easier. This will make more sense as you view the detailed description of each of the D365 collection classes.

Containers

Similarly, containers can be used to store values. One of the very cool things about containers is that they can store values of different data types. However, containers can only be used to store primitive data types. They cannot be used to store objects or class objects. Attempting to store a objects in a container will result in a compile-time or runtime error.

Additionally, like with temp tables, containers do not have all of the same helpful methods that D365 collection classes have. Therefore, they are not the best choice when working with lists of values that contain all the same data type.

Microsoft Document

Furthermore, if you would like to learn more about D365 collection classes, check out the Microsoft documentation here.

Conclusion

Many processes often loop through records already saved to the database. However, D365 collection classes are beneficial for storing, finding, and looping through lists that are not in the database. The base Microsoft methods significantly help when working with lists of values, saving developers considerable time. Learning these classes is essential so that you understand how they work when you see them in the base code. Additionally, they help developers write better-performing code that is easier to read and faster to write.

Peter Ramer
Peter Ramer is a part of the Managed Application Services team at RSM working on Microsoft Dynamics 365. He focuses on the Retail and Commerce industries. When he is not solving problems and finding ways to accelerate his clients' business, he enjoys time with his three kids and amazing wife.

Share this:

Leave a Reply

Your email address will not be published. Required fields are marked *

Proudly powered by WordPress | Theme: Baskerville 2 by Anders Noren.

Up ↑