Please ensure Javascript is enabled for purposes of website accessibility
Powered by Zoomin Software. For more details please contactZoomin

AF SDK Reference

AFSearch(T) Class

  • Last UpdatedNov 18, 2025
  • 23 minute read
AFSearch(T) Class
This is an abstract generic class that implements some helper methods for searching and is used as the base class for searching for specific types of objects.

Inheritance Hierarchy

SystemObject
  OSIsoft.AF.SearchAFSearch
    OSIsoft.AF.SearchAFSearchT
      More...

Namespace:  OSIsoft.AF.Search
Assembly:  OSIsoft.AFSDK (in OSIsoft.AFSDK.dll) Version: 3.1.1.1182

Syntax

public abstract class AFSearch<T> : AFSearch, 
	IAFSearch<T>
where T : AFObject
Public MustInherit Class AFSearch(Of T As AFObject)
	Inherits AFSearch
	Implements IAFSearch(Of T)

Dim instance As AFSearch(Of T)
generic<typename T>
where T : AFObject
public ref class AFSearch abstract : public AFSearch, 
	IAFSearch<T>
[<AbstractClassAttribute>]
type AFSearch<'T when 'T : AFObject> =  
    class
        inherit AFSearch
        interface IAFSearch<'T>
    end

Type Parameters

T
Type of AFObject to which the search will apply.

The AFSearchT type exposes the following members.

Properties

  NameDescription
Public property
CacheInterval
The search's cached automatic refresh interval.
(Inherited from AFSearch.)
Public property
CacheTimeout
The timeout to clean up the cached search in the server if it has not been used.
(Inherited from AFSearch.)
Public property
Database
The AFDatabase to be searched by the query.
(Inherited from AFSearch.)
Public property
Identity
This read-only property specifies the identity of the objects returned from the search.
(Inherited from AFSearch.)
Public property
PISystem
The PISystem to be searched by the query.
(Inherited from AFSearch.)
Public property
SearchName
The name of the search object.
(Inherited from AFSearch.)
Public property
ThrowOnError
Specifies it an exception will be thrown for missing objects or invalid data in the query.
(Inherited from AFSearch.)
Public property
TokenCollection
The tokens that represent this search object.
(Inherited from AFSearch.)
Public property
Tokens Obsolete.
The tokens that represent this search object.
(Inherited from AFSearch.)

Methods

  NameDescription
Public methodCode example
Aggregate
Performs all requested aggregates on the objects that match the search criteria.
(Inherited from AFSearch.)
Public methodCode example
AggregateAsync
Performs all requested aggregates on the objects that match the search criteria asynchronously.
(Inherited from AFSearch.)
Public methodCode example
BinnedSummaryTBin
Generates a summary broken down by the specified bins for items matching the search criteria.
(Inherited from AFSearch.)
Public methodCode example
BinnedSummaryAsyncTBin
Generates a summary broken down by the specified bins for items matching the search criteria asynchronously.
(Inherited from AFSearch.)
Public method
Close
Closes the search that is cached in the server.
(Inherited from AFSearch.)
Public method
Equals
Determines whether the specified object is equal to the current object.
(Inherited from Object.)
Public methodCode example
FindObjectFields(String, Int32, Int32)
This method will return the values as an IList for the specified fields for each of the objects that match the search tokens.
(Overrides AFSearchFindObjectFields(String, Int32, Int32).)
Public methodCode example
FindObjectFieldsTObject(Int32, Int32)
This method will return the values for the fields defined by the user-defined type for each of the objects that match the search tokens.
(Overrides AFSearchFindObjectFieldsTObject(Int32, Int32).)
Public methodCode example
FindObjectFieldsTObject(String, FuncIListObject, TObject, Int32, Int32)
This method will return the values as an object for the specified fields for each of the objects that match the search tokens using the supplied factory delegate.
(Inherited from AFSearch.)
Public methodCode example
FindObjectFieldsTObject(String, FuncIListObject, TObject, Int32, Int32)
This method will return the values as an object for the specified fields for each of the objects that match the search tokens using the supplied factory delegate.
(Overrides AFSearchFindObjectFieldsTObject(String, FuncIListObject, TObject, Int32, Int32).)
Public methodCode example
FindObjectIds
This method will return a list of the ID for each object that matches the search tokens.
(Overrides AFSearchFindObjectIds(Int32, Int32).)
Public methodCode example
FindObjects
This method will return the objects that match the search tokens.
Public methodCode example
FrequencyDistribution
Generates a frequency distribution for the specified items.
(Inherited from AFSearch.)
Public methodCode example
FrequencyDistributionAsync
Generates a frequency distribution for the specified items asynchronously.
(Inherited from AFSearch.)
Public method
GetHashCode
Serves as the default hash function.
(Inherited from Object.)
Public method
GetTotalCount
Returns the total count of the items that could be returned from the search query.
(Overrides AFSearchGetTotalCount.)
Public method
GetType
Gets the Type of the current instance.
(Inherited from Object.)
Public methodCode example
GroupedSummary
Generates summaries broken down by group for items matching the search criteria.
(Inherited from AFSearch.)
Public methodCode example
GroupedSummaryAsync
Generates summaries broken down by group for items matching the search criteria asynchronously.
(Inherited from AFSearch.)
Public methodCode example
HistogramTBin
Generates a histogram using the specified weighting for items matching this search.
(Inherited from AFSearch.)
Public methodCode example
HistogramAsyncTBin
Generates a histogram using the specified weighting for items matching this search asynchronously.
(Inherited from AFSearch.)
Public methodCode example
IsMatch
Determines if the specified item matches the search query.
Public method
Refresh
Refreshes the search that is cached in the server.
(Inherited from AFSearch.)
Public methodCode example
Summary(String, AFSummaryTypes)
Summarizes the result of this search.
(Inherited from AFSearch.)
Public method
Summary(String, AFSummaryTypes, String)
Summarizes the result of this search with the specified weighting.
(Inherited from AFSearch.)
Public methodCode example
SummaryAsync(String, AFSummaryTypes, CancellationToken)
Summarizes the result of this search asynchronously.
(Inherited from AFSearch.)
Public method
SummaryAsync(String, AFSummaryTypes, String, CancellationToken)
Summarizes the result of this search with the specified weighting asynchronously.
(Inherited from AFSearch.)
Public method
ToString
Returns a String that represents the current object.
(Inherited from AFSearch.)
Public method
TryFindSearchToken Obsolete.
Find the AFSearchToken associated with the specified AFSearchFilter.
(Inherited from AFSearch.)
Public method
TryFindSearchTokens Obsolete.
Find the AFSearchToken list associated with the specified AFSearchFilter.
(Inherited from AFSearch.)

Remarks

The search classes that inherit from this base class perform their searches based on a query string that is converted into search tokens. This provides a flexible way to specify the search query, but not all servers will support every combination of filters. The QuerySearch feature can be checked to determine if query searches are supported by the server. If they are not supported by the server, then the SDK will perform the search using existing search methods in the older servers. If the search is too complex for the older servers, an error will be generated.

A query string is parsed into search tokens which are used to specify the query filters for the search.

To optimize getting items from several pages of search results, a search can be cached by setting the CacheTimeout to a non-zero value. If you will only be getting items from the first page, then it is best to leave the cache disabled. The cache is disabled by default. Call the Refresh method to refresh the results of a cached search. Use the Close method to close a cached search when finished using it to free the memory used by the cached results in the server. Since the search implements the IDisposable interface, you can call the cached search in a using statement to automatically call the Close method when it leaves scope.

Note Notes to Callers
When a query is too complex for a server, then you will get a NotSupportedException.

Examples

This example shows how to use the FindObjects method.
// Get the Database
PISystems myPISystems = new PISystems();
PISystem myPISystem = myPISystems.DefaultPISystem;
if (myPISystem == null)
    throw new InvalidOperationException("Default PISystem was not found.");
AFDatabase myDB = myPISystem.Databases[dbName];
if (myDB == null)
    throw new InvalidOperationException("Database was not found.");

// Create a search to find all the elements in a specific area
// of a plant (e.g. 'WestPlant\Area32') and have either a 'Valve' category or a name beginning with 'Valve'.
int count;
using (var search = new AFElementSearch(myDB, "FindValves", @"Root:'WestPlant\Area32' (Category:'Valve' OR Name:Valve*)"))
{
    search.CacheTimeout = TimeSpan.FromMinutes(10);

    // When the elements are returned from a find operation, they are only
    // partially loaded into memory, typically enough to display their 
    // inherent properties, such as Name, Description, Template, Type, etc.  
    // When a piece of information is accessed in the element that requires more 
    // information, an RPC to the server is made to fully load the element.  
    // By having the search do a full load, all information is loaded in bulk and
    // we can reduce the number of RPCs made to retrieve this information.
    count = search.GetTotalCount();
    Console.WriteLine("Found {0} Elements.", count);
    foreach (AFElement item in search.FindObjects(fullLoad: true))
    {
        // Now we can use the elements without having to make any additional RPCs
        // In the example below, accessing the Attributes collection would have 
        // caused an additional RPC per element found.
        // Now we can use the elements without having to make any additional RPCs
        // In the example below, accessing the Attributes collection would have 
        // caused an additional RPC per element found.
        Console.WriteLine("  Element {0} has {1} Attributes", item.Name, item.Attributes.Count);
    }
}
' Get the Database
Dim myPISystems As New PISystems()
Dim myPISystem As PISystem = myPISystems.DefaultPISystem
If myPISystem Is Nothing Then
    Throw New InvalidOperationException("Default PISystem was not found.")
End If
Dim myDB As AFDatabase = myPISystem.Databases(dbName)
If myDB Is Nothing Then
    Throw New InvalidOperationException("Database was not found.")
End If

' Create a search to find all the elements in a specific area
' of a plant (e.g. 'WestPlant\Area32') and have either a 'Valve' or 'Boiler' category.
Dim count As Integer
Using search As New AFElementSearch(myDB, "FindValves", "Root:'WestPlant\Area32' (Category:'Valve' OR Name:Valve*)")

    search.CacheTimeout = TimeSpan.FromMinutes(10)

    ' When the elements are returned from a find operation, they are only
    ' partially loaded into memory, typically enough to display their 
    ' inherent properties, such as Name, Description, Template, Type, etc.  
    ' When a piece of information is accessed in the element that requires more 
    ' information, an RPC to the server is made to fully load the element.  
    ' By having the search do a full load, all information is loaded in bulk and
    ' we can reduce the number of RPCs made to retrieve this information.
    count = search.GetTotalCount()
    Console.WriteLine("Found {0} Elements.", count)
    For Each item As AFElement In search.FindObjects(fullLoad:=True)

        ' Now we can use the elements without having to make any additional RPCs
        ' In the example below, accessing the Attributes collection would have 
        ' caused an additional RPC per element found.
        ' Now we can use the elements without having to make any additional RPCs
        ' In the example below, accessing the Attributes collection would have 
        ' caused an additional RPC per element found.
        Console.WriteLine("  Element {0} has {1} Attributes", item.Name, item.Attributes.Count)
    Next
End Using

No code example is currently available or this language may not be supported.

No code example is currently available or this language may not be supported.

This example shows how to use the FindObjectIds(Int32, Int32) method.
// Get the Database
PISystems myPISystems = new PISystems();
PISystem myPISystem = myPISystems.DefaultPISystem;
if (myPISystem == null)
    throw new InvalidOperationException("Default PISystem was not found.");
AFDatabase myDB = myPISystem.Databases[dbName];
if (myDB == null)
    throw new InvalidOperationException("Database was not found.");

// Use attribute value query to find a list of tanks that are 
// In Service (tanks which are out-of-service have their 
// Status attribute set to "OS").
int totalCount = 0;
using (var search = new AFElementSearch(myDB, "FindTanks", @"Template:'TankAdvanced' |Status:<>'OS'"))
{
    search.CacheTimeout = TimeSpan.FromMinutes(10);

    // Because we are only going to use a few of the attributes for each
    // of the elements found, we can reduce the load time and memory space
    // by just loading the attributes we need.  Note that if we inadvertently
    // use attributes other than these, we will incur a load penalty.
    AFElementTemplate tankTemplate = myDB.ElementTemplates["Tank"];
    AFNamedCollectionList<AFAttributeTemplate> myAttributes =
        new AFNamedCollectionList<AFAttributeTemplate>();
    myAttributes.Add(tankTemplate.AttributeTemplates["Volume"]);
    myAttributes.Add(tankTemplate.AttributeTemplates["Level"]);
    myAttributes.Add(tankTemplate.AttributeTemplates["Level|HighLimit"]);
    myAttributes.Add(tankTemplate.AttributeTemplates["Level|LowLimit"]);

    // Get today's date and UOMs to be used for converting values.
    AFTime today = new AFTime("T", CultureInfo.CurrentCulture);
    UOM bbl = myDB.PISystem.UOMDatabase.UOMs["bbl"];
    UOM meter = myDB.PISystem.UOMDatabase.UOMs["m"];

    const int pageSize = 1000;
    int startIndex = 0;
    IList<Guid> myElementIds = new List<Guid>(pageSize);
    do
    {
        // Find the element IDs and load the attributes we will be using.
        var results = search.FindObjectIds(startIndex, pageSize: pageSize);
        myElementIds.Clear();
        int c = 0;
        foreach (Guid id in results)
        {
            totalCount++;
            myElementIds.Add(id);
            c++;
            if (c >= pageSize)
                break;
        }

        if (myElementIds.Count == 0) break;
        AFNamedCollectionList<AFElement> elements =
            AFElement.LoadAttributes(myPISystem, myElementIds, myAttributes);

        // Once the elements are loaded, we can process them.
        foreach (AFElement element in elements)
        {
            try
            {
                AFAttributeList attributes = new AFAttributeList();
                attributes.Add(element.Attributes["Volume"]);
                attributes.Add(element.Attributes["Level"]);
                attributes.Add(element.Attributes["Level|HighLimit"]);
                attributes.Add(element.Attributes["Level|LowLimit"]);
                AFValues values = attributes.GetValue(today);

                if (values[0].IsGood && values[1].IsGood &&
                    values[2].IsGood && values[3].IsGood)
                {
                    double volume = (double)values[0].Convert(bbl).Value;
                    double level = (double)values[1].Convert(meter).Value;
                    double high = (double)values[2].Convert(meter).Value;
                    double low = (double)values[3].Convert(meter).Value;

                    Console.WriteLine("Tank Inventory for '{0}' is {1} bbl.  %Full={2}",
                        element.Name, volume, 100 * (high - low) / level);
                }
                else
                {
                    Console.WriteLine("Bad data in Tank '{0}'", element.Name);
                }
            }
            catch (FormatException)
            {
                Console.WriteLine("Error in Tank '{0}'", element.Name);
            }
        }

        startIndex += myElementIds.Count; // Advance to next page.
    } while (myElementIds.Count > 0 && myElementIds.Count >= pageSize);
}

Console.WriteLine("Processed {0} Elements.", totalCount);
' Get the Database
Dim myPISystems As New PISystems()
Dim myPISystem As PISystem = myPISystems.DefaultPISystem
If myPISystem Is Nothing Then
    Throw New InvalidOperationException("Default PISystem was not found.")
End If
Dim myDB As AFDatabase = myPISystem.Databases(dbName)
If myDB Is Nothing Then
    Throw New InvalidOperationException("Database was not found.")
End If

' Use attribute value query to find a list of tanks that are 
' In Service (tanks which are out-of-service have their 
' Status attribute set to "OS").
Dim totalCount As Integer = 0
Using search As New AFElementSearch(myDB, "FindTanks", "Template:'TankAdvanced' |Status:<>'OS'")

    search.CacheTimeout = TimeSpan.FromMinutes(10)

    ' Because we are only going to use a few of the attributes for each
    ' of the elements found, we can reduce the load time and memory space
    ' by just loading the attributes we need.  Note that if we inadvertently
    ' use attributes other than these, we will incur a load penalty.
    Dim tankTemplate As AFElementTemplate = myDB.ElementTemplates("Tank")
    Dim myAttributes As New AFNamedCollectionList(Of AFAttributeTemplate)()
    myAttributes.Add(tankTemplate.AttributeTemplates("Volume"))
    myAttributes.Add(tankTemplate.AttributeTemplates("Level"))
    myAttributes.Add(tankTemplate.AttributeTemplates("Level|HighLimit"))
    myAttributes.Add(tankTemplate.AttributeTemplates("Level|LowLimit"))

    ' Get today's date and UOMs to be used for converting values.
    Dim today As New AFTime("T", CultureInfo.CurrentCulture)
    Dim bbl As UOM = myDB.PISystem.UOMDatabase.UOMs("bbl")
    Dim meter As UOM = myDB.PISystem.UOMDatabase.UOMs("m")

    Const pageSize As Integer = 1000
    Dim startIndex As Integer = 0
    Dim myElementIds As IList(Of Guid) = New List(Of Guid)(pageSize)
    Do
        ' Find the elements and load the attributes we will be using.
        Dim results As IEnumerable(Of Guid) = search.FindObjectIds(startIndex, pageSize:=pageSize)
        myElementIds.Clear()
        Dim c As Integer = 0
        For Each id As Guid In results
            totalCount += 1
            myElementIds.Add(id)
            c += 1
            If c >= pageSize Then
                Exit For
            End If
        Next

        If myElementIds.Count = 0 Then
            Exit Do
        End If
        Dim elements As AFNamedCollectionList(Of AFElement) =
            AFElement.LoadAttributes(myPISystem, myElementIds, myAttributes)

        ' Once the elements are loaded, we can process them.
        For Each element As AFElement In elements
            Try
                Dim attributes As New AFAttributeList()
                attributes.Add(element.Attributes("Volume"))
                attributes.Add(element.Attributes("Level"))
                attributes.Add(element.Attributes("Level|HighLimit"))
                attributes.Add(element.Attributes("Level|LowLimit"))
                Dim values As AFValues = attributes.GetValue(today)

                If values(0).IsGood AndAlso values(1).IsGood AndAlso values(2).IsGood AndAlso values(3).IsGood Then
                    Dim volume As Double = CDbl(values(0).Convert(bbl).Value)
                    Dim level As Double = CDbl(values(1).Convert(meter).Value)
                    Dim high As Double = CDbl(values(2).Convert(meter).Value)
                    Dim low As Double = CDbl(values(3).Convert(meter).Value)

                    Console.WriteLine("Tank Inventory for '{0}' is {1} bbl.  %Full={2}", element.Name, volume, 100 * (high - low) / level)
                Else
                    Console.WriteLine("Bad data in Tank '{0}'", element.Name)
                End If
            Catch generatedExceptionName As FormatException
                Console.WriteLine("Error in Tank '{0}'", element.Name)
            End Try
        Next

        ' Advance to next page.
        startIndex += myElementIds.Count
    Loop While myElementIds.Count > 0 AndAlso myElementIds.Count >= pageSize
End Using

Console.WriteLine("Processed {0} Elements.", totalCount)

No code example is currently available or this language may not be supported.

No code example is currently available or this language may not be supported.

This is the type used in the following example for using the FindObjectFields methods.
 1//*************************************************************************
 2/// <summary>
 3/// This class defines the object fields returned from the 
 4/// FindObjectFields method.
 5/// </summary>
 6public class EventFrameFields
 7{
 8    // Field mapped using default name.
 9    public Guid ID;
10    // Property mapped using default name.
11    public string Name { get; set; }
12    // Field mapped using 'ObjectField' attribute.
13    [AFSearch.ObjectField("Duration")]
14    public AFTimeSpan EFDuration;
15    // Property mapped using 'ObjectField' attribute.
16    [AFSearch.ObjectField("StartTime")]
17    public AFTime EFStart { get; set; }
18    // Attribute value mapped to property using 'ObjectField' attribute.
19    [AFSearch.ObjectField("|Level")]
20    public AFValue Level { get; set; }
21}
22
23//*************************************************************************
 1'*************************************************************************
 2''' <summary>
 3''' This class defines the object fields returned from the 
 4''' FindObjectFields method.
 5''' </summary>
 6Public Class EventFrameFields
 7    ' Field mapped using default name.
 8    Public ID As Guid
 9    ' Property mapped using default name.
10    Public Property Name() As String
11        Get
12            Return m_Name
13        End Get
14        Set
15            m_Name = Value
16        End Set
17    End Property
18    Private m_Name As String
19    ' Field mapped using 'ObjectField' attribute.
20    <AFSearch.ObjectField("Duration")>
21    Public EFDuration As AFTimeSpan
22    ' Property mapped using 'ObjectField' attribute.
23    <AFSearch.ObjectField("StartTime")>
24    Public Property EFStart() As AFTime
25        Get
26            Return m_EFStart
27        End Get
28        Set
29            m_EFStart = Value
30        End Set
31    End Property
32    Private m_EFStart As AFTime
33    ' Attribute value mapped to property using 'ObjectField' attribute.
34    <AFSearch.ObjectField("|Level")>
35    Public Property Level() As AFValue
36        Get
37            Return m_Level
38        End Get
39        Set
40            m_Level = Value
41        End Set
42    End Property
43    Private m_Level As AFValue
44End Class
45
46'*************************************************************************

No code example is currently available or this language may not be supported.

No code example is currently available or this language may not be supported.

This example shows how to use the FindObjectFields methods.
// Get the Database
PISystems myPISystems = new PISystems();
PISystem myPISystem = myPISystems.DefaultPISystem;
if (myPISystem == null)
    throw new InvalidOperationException("Default PISystem was not found.");
AFDatabase myDB = myPISystem.Databases[dbName];
if (myDB == null)
    throw new InvalidOperationException("Database was not found.");

// Create a search to find all the event frames created from the 'Event'
// template and its 'Level' attribute value is less than 90.
int count;
using (var search = new AFEventFrameSearch(myDB, "FindEventFields", @"Template:'Event' |Level:<90.0"))
{
    search.CacheTimeout = TimeSpan.FromMinutes(10);

    // Do the search
    // Return specified fields as object list.
    count = 0;
    Console.WriteLine("Find Object Fields:");
    foreach (var row in search.FindObjectFields("ID Name StartTime EndTime |Level"))
    {
        count++;
        foreach (var item in row)
        {
            Console.Write("{0}, ", item);
        }
        Console.WriteLine();
    }
    Console.WriteLine("Found {0} EventFrames.", count);
    // Return specified fields as an anonymous type.
    count = 0;
    var foundItems2 = search.FindObjectFields("ID Name StartTime EndTime |Level",
        i => new { ID = i[0], Name = i[1], Start = i[2], End = i[3], Value = i[4] });
    Console.WriteLine("Find Object Fields using Anonymous Type:");
    foreach (var row in foundItems2)
    {
        count++;
        Console.WriteLine("ID={0}, N='{1}', ST={2}, ET={3}, V={4}",
            row.ID, row.Name, row.Start, row.End, row.Value);
    }
    Console.WriteLine("Found {0} EventFrames.", count);

    // Return event frame name as list of strings.
    count = 0;
    var foundItems3 = search.FindObjectFields("Name", i => i[0].ToString());
    Console.WriteLine("Find Object Names as list of strings:");
    foreach (var row in foundItems3)
    {
        count++;
        Console.WriteLine(row);
    }
    Console.WriteLine("Found {0} EventFrames.", count);
    // 
    // Return event frame security tokens as list and check security for current user.
    count = 0;
    var foundItems4 = search.FindObjectFields("SecurityToken", i => (AFSecurityRightsToken)i[0]);
    Console.WriteLine("Find Object SecurityTokens and Check Security:");
    foreach (var tokenList in foundItems4.ChunkedBy(500))
    {
        // Check Security using Windows Identity.
        var rights = AFSecurity.CheckSecurity(myPISystem, WindowsIdentity.GetCurrent(), tokenList);
        foreach (var rightsItem in rights)
        {
            Console.WriteLine($"  Security Rights for '{myPISystem.CurrentUserName}': {rightsItem.Key} = {rightsItem.Value}");
        }

        // Check Security using Identities.
        rights = AFSecurity.CheckSecurity(myPISystem, myPISystem.CurrentUserIdentities, tokenList, myPISystem.CurrentUserName);
        foreach (var rightsItem in rights)
        {
            Console.WriteLine($"  Security Rights for '{myPISystem.CurrentUserIdentityString}': {rightsItem.Key} = {rightsItem.Value}");
        }
        count += tokenList.Count;
    }
    Console.WriteLine("Found {0} EventFrames.", count);
    // Return specified fields using dynamic type conversion.
    count = 0;
    var foundDynItems = search.FindObjectFields<EventFrameFields>();
    Console.WriteLine("Find Object Fields using Dynamic Type Conversion:");
    foreach (var row in foundDynItems)
    {
        count++;
        Console.WriteLine("ID={0}, N='{1}', ST={2}, D={3}, V={4}",
            row.ID, row.Name, row.EFStart, row.EFDuration, row.Level);
    }
    Console.WriteLine("Found {0} EventFrames.", count);
}
' Get the Database
Dim myPISystems As New PISystems()
Dim myPISystem As PISystem = myPISystems.DefaultPISystem
If myPISystem Is Nothing Then
    Throw New InvalidOperationException("Default PISystem was not found.")
End If
Dim myDB As AFDatabase = myPISystem.Databases(dbName)
If myDB Is Nothing Then
    Throw New InvalidOperationException("Database was not found.")
End If

' Create a search to find all the event frames created from the 'Event'
' template and its 'Level' attribute value is less than 90.
Dim count As Integer
Using search As New AFEventFrameSearch(myDB, "FindEventFields", "Template:'Event' |Level:<90.0")

    search.CacheTimeout = TimeSpan.FromMinutes(10)

    ' Do the search

    ' Return specified fields as object list.
    count = 0
    Console.WriteLine("Find Object Fields:")
    For Each row As IList(Of Object) In search.FindObjectFields("ID Name StartTime EndTime |Level")
        count += 1
        For Each item As Object In row
            Console.Write("{0}, ", item)
        Next
        Console.WriteLine()
    Next
    Console.WriteLine("Found {0} EventFrames.", count)

    ' Return specified fields as an anonymous type.
    count = 0
    Dim foundItems2 = search.FindObjectFields("ID Name StartTime EndTime |Level",
                        Function(i) New With {.ID = i(0), .Name = i(1), .Start = i(2), .[End] = i(3), .Value = i(4)})
    Console.WriteLine("Find Object Fields using Anonymous Type:")
    For Each row In foundItems2
        count += 1
        Console.WriteLine("ID={0}, N='{1}', ST={2}, ET={3}, V={4}", row.ID, row.Name, row.Start, row.[End], row.Value)
    Next
    Console.WriteLine("Found {0} EventFrames.", count)

    ' Return event frame name as list of strings.
    count = 0
    Dim foundItems3 = search.FindObjectFields("Name", Function(i) i(0).ToString())
    Console.WriteLine("Find Object Names as list of strings:")
    For Each row As String In foundItems3
        count += 1
        Console.WriteLine(row)
    Next
    Console.WriteLine("Found {0} EventFrames.", count)

    ' Return event frame security tokens as list and check security for current user.
    count = 0
    Dim foundItems4 = search.FindObjectFields("SecurityToken", Function(i) CType(i(0), AFSecurityRightsToken))
    Console.WriteLine("Find Object SecurityTokens and Check Security:")
    For Each tokenList In foundItems4.ChunkedBy(500)
        ' Check Security using Windows Identity.
        Dim rights = AFSecurity.CheckSecurity(myPISystem, WindowsIdentity.GetCurrent, tokenList)
        For Each rightsItem In rights
            Console.WriteLine($"  Security Rights for '{myPISystem.CurrentUserName}': {rightsItem.Key} = {rightsItem.Value}")
        Next

        ' Check Security using Identities.
        rights = AFSecurity.CheckSecurity(myPISystem, myPISystem.CurrentUserIdentities, tokenList, myPISystem.CurrentUserName)
        For Each rightsItem In rights
            Console.WriteLine($"  Security Rights for '{myPISystem.CurrentUserIdentityString}': {rightsItem.Key} = {rightsItem.Value}")
        Next
        count = (count + tokenList.Count)
    Next
    Console.WriteLine("Found {0} EventFrames.", count)

    ' Return specified fields using dynamic type conversion.
    count = 0
    Dim foundDynItems = search.FindObjectFields(Of EventFrameFields)()
    Console.WriteLine("Find Object Fields using Dynamic Type Conversion:")
    For Each row In foundDynItems
        count += 1
        Console.WriteLine("ID={0}, N='{1}', ST={2}, D={3}, V={4}", row.ID, row.Name, row.EFStart, row.EFDuration, row.Level)
    Next
    Console.WriteLine("Found {0} EventFrames.", count)

End Using

No code example is currently available or this language may not be supported.

No code example is currently available or this language may not be supported.

This example shows how to use the to find event frames. Similar examples for each of the search objects in their class description.
 1// Get the Database
 2PISystems myPISystems = new PISystems();
 3PISystem myPISystem = myPISystems.DefaultPISystem;
 4if (myPISystem == null)
 5    throw new InvalidOperationException("Default PISystem was not found.");
 6AFDatabase myDB = myPISystem.Databases[dbName];
 7if (myDB == null)
 8    throw new InvalidOperationException("Database was not found.");
 9
10// Create a search to find all the event frames created from the 'Event'
11// template, with a start time greater than or equal to three days ago,
12// and its 'Level' attribute value is greater than or equal 45.
13// Note: Time strings must be in a format supported by AFTime.Parse which
14//       will use current culture and then fall back to invariant culture.
15int count;
16using (var search = new AFEventFrameSearch(myDB, "FindEvents", @"Template:'Event' Start:>='*-3d' |Level:>=45.0"))
17{
18    search.CacheTimeout = TimeSpan.FromMinutes(10);
19
20    // When the event frames are returned from a find operation, they are only
21    // partially loaded into memory, typically enough to display their 
22    // inherent properties, such as Name, Description, Template, etc.  
23    // When a piece of information is accessed in the event frame that requires more 
24    // information, an RPC to the server is made to fully load the event frame.  
25    // By having the search do a full load, all information is loaded in bulk and
26    // we can reduce the number of RPCs made to retrieve this information.
27    count = search.GetTotalCount();
28    Console.WriteLine("Found {0} EventFrames.", count);
29    foreach (AFEventFrame item in search.FindObjects(fullLoad: true))
30    {
31        // Now we can use the event frames without having to make any additional RPCs
32        // In the example below, accessing the Attributes collection would have 
33        // caused an additional RPC per element found.
34        // Now we can use the event frames without having to make any additional RPCs
35        // In the example below, accessing the Attributes collection would have 
36        // caused an additional RPC per event frame found.
37        Console.WriteLine("  EventFrame {0} has {1} Attributes", item.Name, item.Attributes.Count);
38    }
39}
 1' Get the Database
 2Dim myPISystems As New PISystems()
 3Dim myPISystem As PISystem = myPISystems.DefaultPISystem
 4If myPISystem Is Nothing Then
 5    Throw New InvalidOperationException("Default PISystem was not found.")
 6End If
 7Dim myDB As AFDatabase = myPISystem.Databases(dbName)
 8If myDB Is Nothing Then
 9    Throw New InvalidOperationException("Database was not found.")
10End If
11
12' Create a search to find all the event frames created from the 'Event'
13' template, with a start time greater than or equal to three days ago,
14' and its 'Level' attribute value is greater than or equal 45.
15' Note: Time Strings must be in a format supported by AFTime.Parse which
16'       will use current culture And then fall back to invariant culture.
17Dim count As Integer
18Using search As New AFEventFrameSearch(myDB, "FindEvents", "Template:'Event' Start:>='*-3d' |Level:>=45.0")
19
20    search.CacheTimeout = TimeSpan.FromMinutes(10)
21
22    ' When the event frames are returned from a find operation, they are only
23    ' partially loaded into memory, typically enough to display their 
24    ' inherent properties, such as Name, Description, Template, etc.  
25    ' When a piece of information is accessed in the event frame that requires more 
26    ' information, an RPC to the server is made to fully load the event frame.  
27    ' By having the search do a full load, all information is loaded in bulk and
28    ' we can reduce the number of RPCs made to retrieve this information.
29    count = search.GetTotalCount()
30    Console.WriteLine("Found {0} EventFrames.", count)
31    For Each item As AFEventFrame In search.FindObjects(fullLoad:=True)
32        ' Now we can use the event frames without having to make any additional RPCs
33        ' In the example below, accessing the Attributes collection would have 
34        ' caused an additional RPC per element found.
35        ' Now we can use the event frames without having to make any additional RPCs
36        ' In the example below, accessing the Attributes collection would have 
37        ' caused an additional RPC per event frame found.
38        Console.WriteLine("  EventFrame {0} has {1} Attributes", item.Name, item.Attributes.Count)
39    Next
40End Using

No code example is currently available or this language may not be supported.

No code example is currently available or this language may not be supported.

Version Information

AFSDK

Supported in: 3.1.1, 3.1.0, 3.0.2, 3.0.1, 3.0.0, 2.10.11, 2.10.5

See Also

Inheritance Hierarchy

SystemObject
  OSIsoft.AF.SearchAFSearch
    OSIsoft.AF.SearchAFSearchT
      OSIsoft.AF.SearchAFAnalysisSearch
      OSIsoft.AF.SearchAFAnalysisTemplateSearch
      OSIsoft.AF.SearchAFAttributeSearch
      OSIsoft.AF.SearchAFCaseSearch
      OSIsoft.AF.SearchAFElementSearch
      OSIsoft.AF.SearchAFEventFrameSearch
      OSIsoft.AF.SearchAFNotificationContactTemplateSearch
      OSIsoft.AF.SearchAFNotificationRuleSearch
      OSIsoft.AF.SearchAFNotificationRuleTemplateSearch
      OSIsoft.AF.SearchAFTransferSearch
TitleResults for “How to create a CRG?”Also Available in