Click or drag to resize
OSIsoft, LLC

Version Example

The following example demonstrates creating a hierarchy of elements, adding new versions of the elements, and then accessing those versions using different approaches.

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

See Also
Enabling Operational Intelligence