Skip to main content
PI System
AF SDK
C#

Traversing an AF Database Hierarchy to Count All Elements Using OSIsoft AF SDK

Learn how to use the OSIsoft AF SDK in C# to traverse an AF database and count all elements within its hierarchy. This blog post provides a comprehensive guide with code examples for connecting, traversing, and counting AF elements.

Roshan Soni

8 min read

Managing and analyzing data within the PI System's Asset Framework (AF) often requires an understanding of the structure and contents of your AF database. One common task is to determine the total number of elements across the entire hierarchy of an AF database. In this blog, we'll explore how to use the OSIsoft AF SDK in C# to traverse an AF database and count all elements within its hierarchy.

Table of Contents


Introduction to OSIsoft AF SDK

The OSIsoft AF SDK is a .NET-based library that allows developers to interact with the PI System's Asset Framework programmatically. It provides a rich set of classes and methods to manage assets, attributes, events, and more.

By leveraging the AF SDK, we can connect to an AF server, access databases, and traverse the hierarchical structures of elements and attributes.

Prerequisites

Before diving into the code, ensure you have the following:

  • OSIsoft AF SDK Installed: Download and install the AF SDK from the OSIsoft Customer Portal.
  • Visual Studio: Any recent version will suffice.
  • Access to an AF Server and Database: You'll need the server and database names to connect.
  • Basic Knowledge of C#: Familiarity with C# programming is assumed.

Connecting to the AF Database

The first step is to connect to the AF server and select the desired database.

using OSIsoft.AF;
using OSIsoft.AF.Asset;

// ...

// Connect to PI System
PISystems piSystems = new PISystems();
string afServerName = "YourAFServerName"; // Replace with your AF Server name
string afDatabaseName = "YourAFDatabaseName"; // Replace with your AF Database name

PISystem piSystem = piSystems[afServerName];
if (piSystem == null)
{
    Console.WriteLine("AF Server not found.");
    return;
}

AFDatabase afDatabase = piSystem.Databases[afDatabaseName];
if (afDatabase == null)
{
    Console.WriteLine("AF Database not found.");
    return;
}

Console.WriteLine($"Connected to AF Database: {afDatabase.Name}");

Explanation

  • PISystems: Represents a collection of PI System servers available on the network.
  • PISystem: Represents a connection to a specific AF server.
  • AFDatabase: Represents a specific database within the AF server.

Note: Replace "YourAFServerName" and "YourAFDatabaseName" with your actual server and database names.

Traversing the Element Hierarchy

AF elements are organized hierarchically, with elements potentially containing child elements. To traverse this structure, we'll use a recursive method.

static int GetTotalElementCount(AFElements elements)
{
    int count = 0;
    foreach (AFElement element in elements)
    {
        count++;
        count += GetTotalElementCount(element.Elements); // Recursively count child elements
    }
    return count;
}

Explanation

  • GetTotalElementCount: A recursive method that takes an AFElements collection.
  • count: An integer variable that keeps track of the total number of elements.
  • foreach Loop: Iterates through each AFElement in the collection.
    • count++: Increments the count for the current element.
    • Recursive Call: GetTotalElementCount(element.Elements) counts all child elements of the current element.

Counting the Elements

Now, we'll call the GetTotalElementCount method starting from the root elements of the database.

// Get total element count
int totalCount = GetTotalElementCount(afDatabase.Elements);
Console.WriteLine($"Total element count across hierarchy: {totalCount}");

Explanation

  • afDatabase.Elements: Retrieves the root elements of the database.
  • totalCount: Stores the total number of elements returned by the method.
  • Console.WriteLine: Outputs the total count to the console.

Full Code Example

Below is the complete code combining all the sections above.

using System;
using OSIsoft.AF;
using OSIsoft.AF.Asset;

namespace AFElementCounter
{
    class Program
    {
        static void Main(string[] args)
        {
            // Connect to PI System
            PISystems piSystems = new PISystems();
            string afServerName = "YourAFServerName"; // Replace with your AF Server name
            string afDatabaseName = "YourAFDatabaseName"; // Replace with your AF Database name

            PISystem piSystem = piSystems[afServerName];
            if (piSystem == null)
            {
                Console.WriteLine("AF Server not found.");
                return;
            }

            AFDatabase afDatabase = piSystem.Databases[afDatabaseName];
            if (afDatabase == null)
            {
                Console.WriteLine("AF Database not found.");
                return;
            }

            Console.WriteLine($"Connected to AF Database: {afDatabase.Name}");

            // Get total element count
            int totalCount = GetTotalElementCount(afDatabase.Elements);
            Console.WriteLine($"Total element count across hierarchy: {totalCount}");
        }

        static int GetTotalElementCount(AFElements elements)
        {
            int count = 0;
            foreach (AFElement element in elements)
            {
                count++;
                count += GetTotalElementCount(element.Elements); // Recursively count child elements
            }
            return count;
        }
    }
}

Running the Code

Steps

  1. Create a New Project: Open Visual Studio and create a new Console Application project.
  2. Add AF SDK Reference:
    • Right-click on the project in the Solution Explorer.
    • Select Add Reference.
    • Browse to the AF SDK installation directory, typically C:\Program Files (x86)\PIPC\AF\PublicAssemblies\4.0\.
    • Select OSIsoft.AFSDK.dll and add it to your project.
  3. Replace Placeholder Strings:
    • Replace "YourAFServerName" with your actual AF server name.
    • Replace "YourAFDatabaseName" with your actual AF database name.
  4. Build and Run:
    • Build the solution to ensure there are no errors.
    • Run the application. The total element count will be displayed in the console.

Sample Output

Connected to AF Database: MyAFDatabase
Total element count across hierarchy: 125

Conclusion

By recursively traversing the element hierarchy in an AF database, we can effectively count all elements, regardless of their depth in the structure. This approach is efficient and leverages the capabilities of the OSIsoft AF SDK.

Understanding how to navigate the AF hierarchy programmatically opens up numerous possibilities for data analysis, reporting, and automation within the PI System.

References


Disclaimer: Ensure you have the necessary permissions to access and query your organization's AF databases. Unauthorized access may violate company policies or data governance regulations.

Tags

#PI System
#AF SDK
#AF Database
#Traversal
#Element Counting
#C#

About Roshan Soni

Expert in PI System implementation, industrial automation, and data management. Passionate about helping organizations maximize the value of their process data through innovative solutions and best practices.

Sign in to comment

Join the conversation by signing in to your account.

Comments (2)

Join the discussion about "Traversing an AF Database Hierarchy to Count All Elements Using OSIsoft AF SDK"

Meet Vyas
171 days ago

Just testing!

September 11, 2025 at 10:15 AM
Meet Vyas
171 days ago

Just testing!

September 11, 2025 at 10:32 AM

Related Articles

Enhancing PI ProcessBook Trends with Banding and Zones: User Needs, Workarounds, and the Road Ahead

A look at the user demand for trend banding/zoning in OSIsoft PI ProcessBook, current VBA workarounds, UI challenges, and how future PI Vision releases aim to address these visualization needs.

Roshan Soni

Migrating PIAdvCalcFilVal Uptime Calculations from PI DataLink to PI OLEDB

Learn how to translate PI DataLink's PIAdvCalcFilVal advanced calculations—like counting uptime based on conditions—into efficient PI OLEDB SQL queries. Explore three practical approaches using PIAVG, PIINTERP, and PICOunt tables, and get tips for validation and accuracy.

Roshan Soni

Understanding PI Web API WebID Encoding: Can You Generate WebIDs Client-Side?

Curious about how PI Web API generates WebIDs and whether you can encode them client-side using GUIDs or paths? This article explores the encoding mechanisms, current documentation, and best practices for handling WebIDs in your applications.

Roshan Soni