Version Example
- Last UpdatedNov 18, 2025
- 11 minute read
- PI System
- AF SDK 2024 R2
- Developer
The following example demonstrates creating a hierarchy of elements, adding new versions of the elements, and then accessing those versions using different approaches.
1// local function to display an error message in the console 2static void ShowError(string message, string title) 3{ 4 ConsoleColor originalColor = Console.ForegroundColor; 5 Console.ForegroundColor = ConsoleColor.Red; 6 7 Console.WriteLine($"{title} --- {message}"); 8 9 Console.ForegroundColor = originalColor; 10} 11 12// Get the Database 13PISystems myPISystems = new PISystems(); 14AFDatabase myDB = myPISystems.DefaultPISystem.Databases.DefaultDatabase; 15 16// Create an Element Template 17AFElementTemplate myElemTemplate = myDB.ElementTemplates.Add("MyElementTemplate"); 18myElemTemplate.Description = "Template used to create my elements"; 19myElemTemplate.CheckIn(); 20 21// Create effective dates 22AFTime baseTime = new AFTime(new DateTime(1995, 6, 30)); 23AFTime time1 = new AFTime(baseTime.UtcTime.AddDays(1)); // Call this T=1 24AFTime time5 = new AFTime(baseTime.UtcTime.AddDays(5)); // Call this T=5 25AFTime time10 = new AFTime(baseTime.UtcTime.AddDays(10)); // Call this T=10 26AFTime time15 = new AFTime(baseTime.UtcTime.AddDays(15)); // Call this T=15 27AFTime time20 = new AFTime(baseTime.UtcTime.AddDays(20)); // Call this T=20 28 29// Create a parent Element with an effective date of T=1 30AFElement parent1 = myDB.Elements.Add("myParent", myElemTemplate, time1); 31parent1.Description = "Parent Element"; 32parent1.CheckIn(); 33 34// Create a second version of the parent Element with an effective date of T=10. 35// Since the first version of the parent is no longer valid for the query date, 36// the first version of the parent will be marked as deleted. Thus, get the 37// first version of the parent again. 38AFElement parent10 = parent1.Version.Create(time10, "T=10") as AFElement; 39parent1 = parent10.ApplyQueryDate(time10.UtcTime.AddDays(-1)) as AFElement; 40 41// Neither version of the parent Element has a child at this point 42// Add a child Element to parent1 with an effective date of T=5. 43AFElement child5 = parent1.Elements.Add("myChildElement", myElemTemplate, time5); 44child5.CheckIn(); 45parent1.CheckIn(); 46 47// Add a second version to child5 with an effective date of T=15. 48AFElement child15 = child5.Version.Create(time15, "T=15") as AFElement; 49 50// Even though child15 was added to the first version of parent1, it won't 51// show up in the child collection of that parent unless the QueryDate of 52// the parent is set to a value of T=5-9. The reason it won't show up 53// before T=5 is that the child element didn't exist before T=5. The 54// reason it won't show up if T>=10 is that the server will use the second 55// version (with an effective date of T=10) to see who the children of 56// 'myParent' are. 57AFElement searchParent; 58searchParent = parent1.ApplyQueryDate(new AFTime(baseTime.UtcTime.AddDays(4))) as AFElement; // T=4 59if (searchParent.Elements.Count > 0) 60 ShowError("Expected 0 sub-elements", "ERROR1"); 61 62searchParent = parent1.ApplyQueryDate(new AFTime(baseTime.UtcTime.AddDays(9))) as AFElement; // T=9 63if (searchParent.Elements.Count != 1) 64 ShowError("Expected 1 sub-elements", "ERROR2"); 65 66searchParent = parent1.ApplyQueryDate(new AFTime(baseTime.UtcTime.AddDays(11))) as AFElement; // T=11 67if (searchParent.Elements.Count > 0) 68 ShowError("Expected 0 sub-elements", "ERROR3"); 69 70// Now add a different element to the second version (T=10) of the parent element. 71AFElement friend15 = parent10.Elements.Add("myFriendElement", myElemTemplate, time15); 72friend15.Description = "Friend Element"; 73friend15.CheckIn(); 74parent10.CheckIn(); 75 76// Add a second version to the friend element. 77// NOTE: It doesn't matter what order we add the versions. 78AFElement friend5 = friend15.Version.Create(time5, "Friend at T=5") as AFElement; 79 80// Now when we set the QueryDate of a copy of parent1 to T=10, we will 81// get the T=5 version of myFriendElement. This shows how it doesn't 82// matter which version of the parent you have. The QueryDate is used 83// to determine which versions to use to get the children. 84searchParent = parent1.ApplyQueryDate(new AFTime(baseTime.UtcTime.AddDays(11))) as AFElement; // T=11 85AFElement searchItem = searchParent.Elements[0]; 86if (searchItem.UniqueID != friend5.UniqueID) // Make sure we got the right element. 87 ShowError("Retrieved wrong element", "ERROR4"); 88 89if (searchItem.Version.EffectiveDate != time5) // Make sure we got the right version. 90 ShowError("Retrieved wrong version", "ERROR5"); 91 92// Now set the QueryDate to null (which represents the current time). This 93// will return the T=15 version for myFriendElement. 94searchParent = parent1.ApplyQueryDate(null) as AFElement; 95searchItem = searchParent.Elements[0]; 96if (searchItem.UniqueID != friend5.UniqueID) // Make sure we got the right element. 97 ShowError("Retrieved wrong element", "ERROR6"); 98 99if (searchItem.Version.EffectiveDate != time15) // Make sure we got the right version. 100 ShowError("Retrieved wrong version", "ERROR7"); 101 102// Now show we can get the children of the parent element with an effective 103// date of T=1. Set the QueryDate to anything between 5-9 and we will get 104// myChildElement. 105searchParent = parent1.ApplyQueryDate(new AFTime(baseTime.UtcTime.AddDays(7))) as AFElement; // T=7 106searchItem = searchParent.Elements[0]; 107if (searchItem.UniqueID != child5.UniqueID) // Make sure we got the right element. 108 ShowError("Retrieved wrong element", "ERROR8"); 109 110if (searchItem.Version.EffectiveDate != time5) // Make sure we got the right version. 111 ShowError("Retrieved wrong version", "ERROR9"); 112 113// NOTE: There is no way to get the T=15 value of myChildElement from the Elements 114// collection of myParentElement because by the time that version is in effect, the 115// parent element has a different child (i.e. myFriendElement). Once you have a 116// version for myChildElement, you can navigate to other versions using the 117// child5.Version.NextVersion, etc. methods. 118 119// The last thing we need to do is to add some grandchildren elements with 120// an effective date of T=20 to the first value of child element (T=5). 121// The second value of child element (T=15) doesn't have this child. 122AFElement grandChild20 = child5.Elements.Add("myGrandChildElement", myElemTemplate, time20); 123grandChild20.CheckIn(); 124child5.CheckIn(); 125 126// Show how it is impossible to find the grandchild element using SetQueryDate 127// and the Elements collection. This is because grandChild20 has a single 128// value with an effective date of T=20. The value of its parent that has an 129// effective date at or before that time is child15 which doesn't have 130// grandChild as a child element. 131searchParent = child5.ApplyQueryDate(new AFTime(baseTime.UtcTime.AddDays(14))) as AFElement; // T=14 132if (searchParent.Elements.Count > 0) 133 ShowError("Expected 0 sub-elements", "ERROR10"); 134 135searchParent = child5.ApplyQueryDate(new AFTime(baseTime.UtcTime.AddDays(25))) as AFElement; // T=25 136if (searchParent.Elements.Count > 0) 137 ShowError("Expected 0 sub-elements", "ERROR11"); 138 139// The only way to find the reference to grandchild element in the first value of 140// the child element is to use the Version.Children collection. This returns a 141// collection of the elements that are referenced by the owner element without 142// using a query date. 143int totalCount; 144IList children = child5.Version.GetChildren(AFSortField.Name, AFSortOrder.Ascending, 0, 10, out totalCount); 145if (children.Count != 1) 146 ShowError("Expected 1 child", "ERROR12"); 147 148searchItem = children[0] as AFElement; 149if (searchItem.UniqueID != grandChild20.UniqueID) // Make sure we got the right element. 150 ShowError("Retrieved wrong element", "ERROR13"); 151 152if (searchItem.Version.EffectiveDate != time20) // Make sure we got the right version. 153 ShowError("Retrieved wrong version", "ERROR14");
1' lambda expression to display an error message in the console 2Dim showError = Sub(message As String, title As String) 3 Dim originalColor As ConsoleColor = Console.ForegroundColor 4 Console.ForegroundColor = ConsoleColor.Red 5 6 Console.WriteLine($"{title} --- {message}") 7 8 Console.ForegroundColor = originalColor 9 End Sub 10 11' Get the Database 12Dim myPISystems As New PISystems() 13Dim myDB As AFDatabase = myPISystems.DefaultPISystem.Databases.DefaultDatabase 14 15' Create an Element Template 16Dim myElemTemplate As AFElementTemplate = myDB.ElementTemplates.Add("MyElementTemplate") 17myElemTemplate.Description = "Template used to create my elements" 18myElemTemplate.CheckIn() 19 20' Create effective dates 21Dim baseTime As AFTime = New AFTime(New DateTime(1995, 6, 30)) 22Dim time1 As AFTime = New AFTime(baseTime.UtcTime.AddDays(1)) ' Call this T=1 23Dim time5 As AFTime = New AFTime(baseTime.UtcTime.AddDays(5)) ' Call this T=5 24Dim time10 As AFTime = New AFTime(baseTime.UtcTime.AddDays(10)) ' Call this T=10 25Dim time15 As AFTime = New AFTime(baseTime.UtcTime.AddDays(15)) ' Call this T=15 26Dim time20 As AFTime = New AFTime(baseTime.UtcTime.AddDays(20)) ' Call this T=20 27 28' Create a parent Element with an effective date of T=1 29Dim parent1 As AFElement = myDB.Elements.Add("myParent", myElemTemplate, time1) 30parent1.Description = "Parent Element" 31parent1.CheckIn() 32 33' Create a second version of the parent Element with an effective date of T=10. 34' Since the first version of the parent is no longer valid for the query date, 35' the first version of the parent will be marked as deleted. Thus, get the 36' first version of the parent again. 37Dim parent10 As AFElement = CType(parent1.Version.Create(time10, "T=10"), AFElement) 38parent1 = CType(parent10.ApplyQueryDate(time10.UtcTime.AddDays(-1)), AFElement) 39 40' Neither version of the parent Element has a child at this point 41' Add a child Element to parent1 with an effective date of T=5. 42Dim child5 As AFElement = parent1.Elements.Add("myChildElement", myElemTemplate, time5) 43child5.CheckIn() 44parent1.CheckIn() 45 46' Add a second version to child5 with an effective date of T=15. 47Dim child15 As AFElement = CType(child5.Version.Create(time15, "T=15"), AFElement) 48 49' Even though child15 was added to the first version of parent1, it won't 50' show up in the child collection of that parent unless the QueryDate of 51' the parent is set to a value of T=5-9. The reason it won't show up 52' before T=5 is that the child element didn't exist before T=5. The 53' reason it won't show up if T>=10 is that the server will use the second 54' version (with an effective date of T=10) to see who the children of 55' 'myParent' are. 56Dim searchparent As AFElement 57searchparent = CType(parent1.ApplyQueryDate(New AFTime(baseTime.UtcTime.AddDays(4))), AFElement) ' T=4 58If (searchparent.Elements.Count > 0) Then 59 showError("Expected 0 sub-elements", "ERROR1") 60End If 61searchparent = CType(parent1.ApplyQueryDate(New AFTime(baseTime.UtcTime.AddDays(9))), AFElement) ' T=9 62If (searchparent.Elements.Count <> 1) Then 63 showError("Expected 1 sub-elements", "ERROR2") 64End If 65searchparent = CType(parent1.ApplyQueryDate(New AFTime(baseTime.UtcTime.AddDays(10))), AFElement) ' T=10 66If (searchparent.Elements.Count > 0) Then 67 showError("Expected 0 sub-elements", "ERROR3") 68End If 69 70' Now add a different element to the second version (T=10) of the parent element. 71Dim friend15 As AFElement = parent10.Elements.Add("myFriendElement", myElemTemplate, time15) 72friend15.Description = "Friend Element" 73friend15.CheckIn() 74parent10.CheckIn() 75 76' Add a second version to the friend element. 77' NOTE: It doesn't matter what order we add the versions. 78Dim friend5 As AFElement = CType(friend15.Version.Create(time5, "Friend at T=5"), AFElement) 79 80' Now when we set the QueryDate of a copy of parent1 to T=10, we will 81' get the T=5 version of myFriendElement. This shows how it doesn't 82' matter which version of the parent you have. The QueryDate is used 83' to determine which versions to use to get the children. 84searchparent = CType(parent1.ApplyQueryDate(New AFTime(baseTime.UtcTime.AddDays(10))), AFElement) ' T=10 85Dim searchItem As AFElement = searchparent.Elements(0) 86If (searchItem.UniqueID <> friend5.UniqueID) Then ' Make sure we got the right element. 87 showError("Retrieved wrong element", "ERROR4") 88End If 89If (searchItem.Version.EffectiveDate <> time5) Then ' Make sure we got the right version. 90 showError("Retrieved wrong version", "ERROR5") 91End If 92 93' Now set the QueryDate to null (which represents the current time). This 94' will return the T=15 version for myFriendElement. 95searchparent = CType(parent1.ApplyQueryDate(Nothing), AFElement) 96searchItem = searchparent.Elements(0) 97If (searchItem.UniqueID <> friend5.UniqueID) Then ' Make sure we got the right element. 98 showError("Retrieved wrong element", "ERROR6") 99End If 100If (searchItem.Version.EffectiveDate <> time15) Then ' Make sure we got the right version. 101 showError("Retrieved wrong version", "ERROR7") 102End If 103 104' Now show we can get the children of the parent element with an effective 105' date of T=1. Set the QueryDate to anything between 5-9 and we will get 106' myChildElement. 107searchparent = CType(parent1.ApplyQueryDate(New AFTime(baseTime.UtcTime.AddDays(7))), AFElement) ' T=7 108searchItem = searchparent.Elements(0) 109If (searchItem.UniqueID <> child5.UniqueID) Then ' Make sure we got the right element. 110 showError("Retrieved wrong element", "ERROR8") 111End If 112If (searchItem.Version.EffectiveDate <> time5) Then ' Make sure we got the right version. 113 showError("Retrieved wrong version", "ERROR9") 114End If 115 116' NOTE: There is no way to get the T=15 value of myChildElement from the Elements 117' collection of myParentElement because by the time that version is in effect, the 118' parent element has a different child (i.e. myFriendElement). Once you have a 119' version for myChildElement, you can navigate to other versions using the 120' child5.Version.NextVersion, etc. methods. 121 122' The last thing we need to do is to add some grandchildren elements with 123' an effective date of T=20 to the first value of child element (T=5). 124' The second value of child element (T=15) doesn't have this child. 125Dim grandChild20 As AFElement = child5.Elements.Add("myGrandChildElement", myElemTemplate, time20) 126grandChild20.CheckIn() 127child5.CheckIn() 128 129' Show how it is impossible to find the grandchild element using SetQueryDate 130' and the Elements collection. This is because grandChild20 has a single 131' value with an effective date of T=20. The value of its parent that has an 132' effective date at or before that time is child15 which doesn't have 133' grandChild as a child element. 134searchparent = CType(child5.ApplyQueryDate(New AFTime(baseTime.UtcTime.AddDays(14))), AFElement) ' T=14 135If (searchparent.Elements.Count > 0) Then 136 showError("Expected 0 sub-elements", "ERROR10") 137End If 138searchparent = CType(child5.ApplyQueryDate(New AFTime(baseTime.UtcTime.AddDays(25))), AFElement) ' T=25 139If (searchparent.Elements.Count > 0) Then 140 showError("Expected 0 sub-elements", "ERROR11") 141End If 142 143' The only way to find the reference to grandchild element in the first value of 144' the child element is to use the Version.Children collection. This returns a 145' collection of the elements that are referenced by the owner element without 146' using a query date. 147Dim totalCount As Integer 148Dim children As IList = child5.Version.GetChildren(AFSortField.Name, AFSortOrder.Ascending, 0, 10, totalCount) 149If (children.Count <> 1) Then 150 showError("Expected 1 child", "ERROR12") 151End If 152searchItem = CType(children(0), AFElement) 153If (searchItem.UniqueID <> grandChild20.UniqueID) Then ' Make sure we got the right element. 154 showError("Retrieved wrong element", "ERROR13") 155End If 156If (searchItem.Version.EffectiveDate <> time20) Then ' Make sure we got the right version. 157 showError("Retrieved wrong version", "ERROR14") 158End If
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.