Skip to content

Business modules of the MIKE OPERATIONS platform

Introduction

This document focuses on how to use the business modules of the MIKE OPERATIONS platform.

It should be read first in order to better understand other documentation documents.

What is a business module?

A business module is a class that provides methods to handle entities, such as time series, features, or scenarios, in each manager of the MIKE OPERATIONS platform. It is the model part in the model-view-controller or MVC design pattern, i.e. it consists of application data that the views work on as well as business rules for manipulating or analysing the data. A user can use this module to work with entities in his own programs or python scripts.

The business module in the MIKE OPERATIONS framework consists of the following important parts:

  • The Module class itself, which provides access to the entity lists and methods to manipulate the entities.

  • The EntityList, GroupedEntityList and GroupEntityList. These are responsible for accessing and organizing entities. EntityList is the base class for handling Entity’s. GroupedEntityList defines methods to work with GroupedEntity’s. While, GroupEntityList is used to work with Group’s.

  • The Entity, GroupedEntity and Group define properties and methods for different entity types in the MIKE OPERATIONS platform. Entity is a base class which is a component containing data and information. GroupedEntity is a type of entity that belongs to a group and is shown as the item under a folder in the user interface. The Group class corresponds to the folder in the user interface. A Group is in itself an Entity and can be part of another Group just like nested folders.

Following figure shows the conceptual relationship among the above parts.

Figure 1 Conceptual diagram to depict the relationship among module, list, entity, and group

Following figure shows the Explorer for the Time Series Manager as an example and demonstrates the folder structure in the user interface.

Figure 2 Time Series Explorer

Notes:

  1. The “JMP” folder is a Group entity.

  2. The “Rainfall 1” node is a GroupedEntity.

Please refer to the Business module structure section below to learn more about the structure of the business modules in the MIKE OPERATIONS platform.

The following sections illustrate how to use methods in the manager module and the entity list classes to implement various common functions.

Reading a time series

This section describes how to read a time series from the database. References to assemblies in Table 1 need to be added before following the steps below.

Table 1 Assemblies which need to be referenced

Assembly Description
DHI.Solutions.Application Functionality for logging in to the MIKE OPERATIONS application.
DHI.Solutions.Generic Basic MIKE OPERATIONS framework functionality.
DHI.Solutions.TimeSeriesManager.Interfaces Time series management interfaces.

Step 1 – Log in to the application

First create a new Application instance and then log in to a workspace as shown in the following listing.

Listing 1 Logging in to the application

Notes:

  1. Log in to the application. Listing 1 uses “dssuser”, “userpassword” and “workspace1” as an example. Other values can be input according to the application’s settings.

  2. Use the StartUp() method to load business components to the application like modules and tools.

Step 2 – Get the time series module

Use the following method to get the time series module after logging in to the application.

Listing 2 Get the time series module

The ITimeSeriesModule interface inherits from IListModule which is described in the Business module structure section. It contains four entity list definitions. Table 2 introduces these definitions.

Table 2 EntityList properties in ITimeSeriesModule

Property Description
TimeSeriesList Implements the ITimeSeriesList interface and is responsible for dealing with the IDataSeries entity.
TimeSeriesGroupList Implements the ITimeSeriesGroupList interface and is responsible for dealing with the time series group entity.
FlagDefinitionList Implements the IFlagDefinitionList interface and is responsible for dealing with the time series flag entity.
TimeSeriesFeatureAssociationList Implements the ITimeSeriesFeatureAssociationList interface and is responsible for dealing with the time series feature association entity which stores information on the association between a time series and a GIS feature.

Step 3 – Get the time series

Use the TimeSeriesList property to get a time series from the database. TimeSeriesList inherits from the BaseGroupedEntityList\<IDataSeries, ITimeSeriesGroup> class and implements the ITimeSeriesList interface. It can be accessed from the time series Module. If the full path of a time series is known, use the method in Listing 3 to get it.

Listing 3 Get the time series via its full path

Use the following method to get a time series if its ID is available. The ID is usually retrieved from another method, rather than entered literally, and can be passed to the Fetch() method to get the time series it specifies.

Listing 4 Get the time series via its ID

Step 4 – Get the values of a time series

Use methods in the IDataSeries entity to read the data from a time series. Table 3 lists the methods that can be used for accessing the actual time series values.

Table 3 Methods related to read data in the IDataSeries interface

Function Description
FetchAll() Gets all of the time series data directly from the database. This forces the database to be re-queried and is slower than GetAll(), but it guarantees the latest data is retrieved.
GetAll() Reads the data values cached in memory that have been populated previously with the Query() method. (Note that using any of the Fetch() methods will also update cached entities.)
Fetch(IQuery query) Gets a list of time series data directly from the database which match the conditions specified by the query.
Get(int index) Gets the data at the specified index from the cached list.
GetValue(DateTime dataTime) Gets the value at the given date time for a time series.

Take FetchAll() as an example. This method returns a list of IDataSeriesValuePair objects. The IDataSeriesValuePair object contains the data for one time step of a time series. The value on the X (time) axis, the value on the Y axis, and the value of the flag can be gotten from this object. This object will be introduced in detail in the Hints and best practices section. Listing 5 shows how to use the FetchAll() method.

Listing 5 FetchAll() method

Another way to get the data directly is to use the GetTimeSeriesValues(object timeSeriesId) method in the TimeSeriesList. If the ID of a time series is known, this method can be used to read all data of a time series from the database, as is shown in Listing 6.

Listing 6 Using GetTimeSeriesValues(object timeSeriesId) to get the data

After getting values of a time series using the above methods, the list of value pair entities will be cached in memory. So in order to avoid a memory leak, please use the ClearData() method of the IDataSeries interface to clear the cached data when the data values are not used any more.

Creating a time series

This walk through describes how to create a new time series and save it to the database. The assemblies in Table 1 above will again need to be referenced.

The first and second steps to create a time series are same as the first and second steps in A walk through – reading a time series. After getting the time series module, follow the steps below to create a new time series in the database.

Step 1 – Create a new empty time series

Use the CreateNew() method to create a time series without defining its name or its parent group.

Listing 7 Create a new time series via the CreateNew() method

Next, set its name and parent group separately.

Listing 8 Set the name and parent group of the newly created time series

The listing performs the following actions:

  1. Set the name of the newly created time series.

  2. Get the parent group based on the full group path.

  3. Set the parent group of the newly created time series.

Alternatively, you can use the CreateNew(string path) method to create a time series in one step with the given fully qualified path, which includes the parent group.

Listing 9 Create a new time series via the CreateNew(string path) method

Step 2 – Set data to the newly created time series

If you already have the IList\<IDataSeriesValuePair> data—fetched from another time series, for example—use SetData(IList\<IDataSeriesValuePair> dataSeriesValuePairList) to set the time series values in the time series object as follows:

Listing 10 Using the SetData(IList\<IDataSeriesValuePair>) method to set time series data

If not, create the list of IDataSeriesValuePair first. The following listing demonstrates the process.

Listing 11 Create a DataSeriesValuePair list first and then set the data for the time series

Notes:

  1. First create a List\<> to contain the IDataSeriesValuePair data.

  2. Then create a new IDataSeriesValuePair object and initialize it.

  3. Next, add the above IDataSeriesValuePair to the List\<>.

  4. Finally set the data for the newly created time series.

Step 3 – Set the time series properties

The IDataSeries entity has many property definitions which describe information about the data and the time series itself. Table 4 lists the properties which are often used.

Table 4 Commonly used properties in IDataSeries

Property Description
XAxisType The type of the X axis. This can be Equidistant, Non_Equidistant, Equidistant_Calendar or Non_Equidistant_Calendar.
XaxisUnit Unit for the X axis.
YaxisUnit Unit for the Y axis.
YaxisVariable The variable type for the Y axis.
ValueType Value type of the Y axis.

Following listing shows an example of how to set these properties.

Listing 12 Set the properties of time series

Step 4 – Save the time series to the database

Before saving the newly created time series to the database, check whether a time series with the same name already exists in the parent group. If yes, then delete the old one or change the name of the newly created time series. Finally, add the time series to the database using the TimeSeriesList. The following listing shows the process.

Listing 13 Save the newly created time series to database

Notes:

  1. Get all of the child time series in the parent group.

  2. Check whether a time series with same name already exists under the parent group.

  3. If it already exists, delete the old one.

  4. Or change the name of the newly created time series.

  5. Save the time series to the database.

Updating an existing time series

This walk through describes how to update an existing time series in the database. Again, remember to reference the assemblies in Table 1.

The first three steps to update a time series are the same as the first three steps in A walk through – reading a time series. That is, in order to update an existing time series, first fetch it from the database. Then follow the steps below to update the time series in the database.

Step 1 – Update the properties of a time series

A time series has a number properties as shown in Table 4. The following listing shows how to update the value type of a time series.

Listing 14 Update the value type of a time series

Notes:

  1. Set a new value to the ValueType property of a time series.

  2. Then use the Update(IDataSeries entity) method of the TimeSeriesList to update the time series in the database.

Step 2 – Update the data values of a time series

If the data of a time series needs to be updated, first follow steps in A walk through – reading a time series to get the data of the time series. Then, set new values to the data list. Finally, update the data in the database. Listing 15 demonstrates the process.

Listing 15 Update the data values of a time series

Notes:

  1. Get one data series value pair from the data list (obtained from the time series)

  2. Update the y value of the data series value pair.

  3. Use the Update(IDataSeriesValuePair dataSeriesValuePair) method to update the changed data in the database.

  4. Create a new list to contain the updated data value pairs.

  5. Update the y values of multiple value pairs in the data list and add the updated value pairs to the new list.

  6. Use the Update(IList\<IDataSeriesValuePair> dataSeriesValuePairList) method to update all the changed data in the database at once.

  7. Change the x value of a value pair.

  8. Clear the cached data of the time series stored in memory.

  9. Use the SetData(IList\<IDataSeriesValuePair> dataSeriesValuePairList) method to set the new data list to the time series in memory.

  10. Use the Update(IDataSeries dataSeries, bool updateData) method to update the data of the time series in the database.

Finding all time series below a given path

This section describes how to find all of the time series below a given path from the database. The assemblies in Table 1 need to be referenced.

The first and second steps to find the child time series are the same as the first and second steps in A walk through – reading a time series. After getting the time series module, use one of the following two ways to get all of the child time series.

Method 1 – Use the FetchChildren method

TimeSeriesList inherits from the BaseGroupedEntityList class, so it has the FetchChildren(string groupPath) method. This method returns an array of the child time series. Listing 16 shows how to use it.

Listing 16 Use FetchChildren(string groupPath) to get all of the child time series

Method 2 – Use the Fetch(IQuery query) method

The Fetch(IQuery query) function returns a list of IDataSeries entities which match the conditions specified by the query. Listing 17 shows how to use it.

Listing 17 Use Fetch(IQuery query) to get all of the child time series

Notes:

  1. Get the parent group by fully qualified group path.

  2. Create a query where the group ID of the result time series is equal the selected group ID.

  3. Fetch the time series from the database that match the query.

Executing a scenario

This section describes how to execute a scenario. In order to handle scenario entities, references to assemblies in Table 5 need to be added to the code project.

Table 5 Assemblies which need to be referenced to work with scenarios

Assembly Description
DHI.Solutions.Application Functionality for logging in to the MIKE OPERATIONS application.
DHI.Solutions.Generic Basic MIKE OPERATIONS framework functionality.
DHI.Solutions.ScenarioManager.Interfaces Scenario management interfaces

The first step to execute a scenario is to log in the application. It is same as the first step in the A walk through – reading a time series. Next, follow the steps below to run a scenario.

Step 1 – Get the scenario module

Use the following to get the scenario module after logging in the application.

Listing 18 Get the scenario module

The IScenarioModule interface also inherits from IListModule.

Step 2 – Get the scenario

Use the ScenarioList class to get a scenario from the database. This class inherits from the BaseEntityList\<IScenario> class and implements the IScenarioList interface. It is responsible for handling the IScenario entity. It can be accessed from the scenario module.

The following listing shows how to get a scenario.

Listing 19 Get a scenario from the database

Notes:

  1. If the full path of a scenario is known, use the Fetch(string path) method to get the scenario.

  2. If the ID of a scenario is available, use the Fetch(object id) method to get the scenario.

Step 3 – Execute the scenario

After getting the scenario from the database, use the RunScenario method in the scenario module to execute the scenario. The following listing shows how to use it.

Listing 20 Call the RunScenario method to execute a scenario

Notes:

  1. First define a simulation variable. It can be set to null.

  2. Then use the RunScenario(IScenario scenario, bool runModelGUI, bool approveSimulation, ref ISimulation simulation) method to run a scenario. This method has four input parameters. The scenario is the one to be executed. The value of runModeGUI indicates whether GUI for the model scenario should be used and shown. The value of approveSimulation indicates whether to approve the simulation automatically while running a scenario. The simulation parameter is a reference object of a simulation.

Getting attributes from a feature class

This walk through describes how to get attributes from a feature class. First, the following assemblies need to be referenced.

Table 6 Assemblies which are needed to be referenced

Assembly Description
DHI.Solutions.Application Functionality for logging in to the MIKE OPERATIONS application.
DHI.Solutions.Generic Basic MIKE OPERATIONS framework functionality.
DHI.Solutions.GISManager.Interfaces GIS management interfaces.

The first step to get feature attributes is to log in to the application which is same as the first step in A walk through – reading a time series. After logging in to the application, follow the steps below to get the attributes of a feature class.

Step 1 – Get the GIS module

Use the following to get the GIS module.

Listing 21 Get the GIS module

The IGISModule interface also inherits from IListModule.

Step 2 – Get the feature class

Use the FeatureClassList class to get a feature class from the database. This class inherits from the BaseGroupedEntityList\<IFeatureClass, IFeatureClassGroup> and implements the IFeatureClassList interface. It is responsible for handling the IFeatureClass entity. It can be accessed from the GIS module.

The following listing demonstrates how to get a feature class.

Listing 22 Get a feature class from the database

Notes:

  1. If the full path of a feature class is available, use the Fetch(string path) method to get it.

  2. If the ID of a feature class is available, use the Fetch(object id) method to get it.

Step 3 – Get the list of feature class attributes

The IFeatureClass entity has a property named AttributeList which is of type IFeatureClassAttributeList. It can be used to work with the feature attributes for a feature class. The following listing shows how to get a list of feature class attributes.

Listing 23 Get a list of IFeatureClassAttribute

The IFeatureClassAttribute is an interface for a feature class attribute. The following table shows the properties of this interface.

Table 7 Properties in the IFeatureClassAttribute interface

Property Description
Name The name of an attribute.
Type The type of an attribute.
MaxLength The maximum length for an attribute. It is only applicable for an attribute of type String.

An attribute’s name, type and maximum length can be obtained through this interface. The following listing illustrates how to get the names of all the countries from a feature class named “Countries” with an attribute called “cntry_name”.

Listing 24 Get the country names from the Countries feature class

Notes:

  1. Get the “Countries” feature class from the database through its full qualified path.

  2. Get the list of IFeatureClassAttribute objects from the countries feature class.

  3. Get the country name attribute from the above attribute list.

  4. Get all of the features of the countries feature class from the database. IFeature is the interface for a feature in a feature class.

  5. Get the list of country names from the countries feature class. Here this[IFeatureClassAttribute attribute] property of the IFeature interface is used.

Hints and best practices

This section provides more details on different aspects related to the use of business modules.

When to use fetch

All of the entity list classes have the Fetch and Get functions. Both types of functions can get entities with the specified full path or entity ID, etc. The difference is that Fetch retrieves entities from the database, while Get returns entities from a cached list which contains references to the data that has been previously loaded.

Entities in the cached list may be different from the ones in the database. For example, a user uses the Query method to cache a list of entities which match specific conditions. That is, not all of the entities are cached. Thus, the user can’t get an entity which does not exist in the cache using the Get method, even if it is actually stored in the database. Another example is when one user has cached data in a list, and then another user deletes one of these entities from the database. The cached list for the first user does not automatically update. So the first user still can get the deleted entity using the Get method. And if he tries to delete the entity, an exception will occur.

Because the data in the cached list may not be consistent with the data in the database, the Fetch method is recommended for use when writing programs or scripts. The Get method would be more appropriate for tasks where performance is an issue, but you will need to take the nature of the cached list into account and use Query (or Fetch) as needed to refresh the cached data.

How to work with IDataSeries objects

IDataSeries is the interface for time series entity. It inherits from a large number of other interfaces. The following figure shows the relationships:

Figure 3 IDataSeries UML class diagram

Table 8 introduces the base interfaces in the above figure.

Table 8 Base interfaces of IDataSeries

Interface Description
INamedEntity Describes an entity with a name. It has a Name property.
IGroupedEntity Describes an entity belonging to a group. It has a GroupId property.
IDTO The interface for data transfer objects used in the data layer.
ICloneable Defines a method for cloning (copying) a data series.
ISelectable A marker (empty) interface telling the system that a data series is selectable.
ITabular An interface for classes with tabular data. Defines a method for building a data table.
ICustomTypeDescriptor Supplies dynamic custom properties information for a data series. This is mainly used for displaying the object in the property control.
IExportable A marker (empty) interface telling the system that a data series is an exportable entity.
IDataSeriesMember An interface for a single member of a time series.
ISelfUpdatable An interface for entities which are self-updatable.

The following section will introduce the IDataSeries interface in detail.

Properties and methods of IDataSeries

The following tables list the properties and methods most often used in the IDataSeries interface.

Table 9 Properties most often used in the IDataSeries interface

Property Description
Id Gets or sets the identifier of a data series entity.
End Gets or sets the last value on the X (time) axis.
EquivalentXAxisUnits Gets an array of units which are equivalent to the X axis unit.
EquivalentYAxisUnits Gets an array of units which are equivalent to the Y axis unit.
IsCalendar Gets a value indicating whether the data series has a calendar X axis.
IsEquidistant Gets a value indicating whether the values on the X axis are equally spaced.
IsReadOnly Gets or sets a value indicating whether a data series can be changed.
Start Gets or sets the first value on the X (time) axis.
TimeStep Gets or sets the time step of a data series. For non-equidistant data series, the value is -1.
XAxisType Gets or sets the type for the X axis.
XAxisUnit Gets the unit for the X axis.
XAxisUnitCode Gets the unit code for the X axis.
YAxisUnit Gets the unit for the Y axis.
YAxisUnitCode Gets the unit code for the Y axis.
YAxisVariable Gets or set the variable for the Y axis.
YAxisVariableCode Gets or set the variable code for the Y axis.
ValueType Gets or set the value type for a data series.
MaxAllowedValue Gets or set the allowed maximum value for a data series.
MinAllowedValue Gets or set the allowed minimum value for a data series.
Members Gets the list of data series members. It is of type IDataSeriesMemberList.
MembersCount Gets the member count of a data series.
TimeZone Gets or set the time zone a data series is in.
Count Gets the number of value pairs contained in the data series.

Table 10 Methods most often used in the IDataSeries interface

Method Description
ClearData() Clears all of the data series value pairs data contained by a data series. This only clears data in the cached object.
SetXAxisUnit() Sets the X axis unit.
SetYAxisUnit() Sets the Y axis unit.
DeleteAll() Deletes all of the data series value pairs from a data series. This also directly deletes data in the database.
Add() Adds one or a list of data series value pairs to the data series and directly to the database.
Merge() Updates existing value pairs and add new value pairs to the data series and directly to the database.
Contains() Gets a value indicating whether an X axis value is contained in the data series. This is for non-Calendar type data series.
CreateNew() Creates a new data series value pair in memory.
Delete() Deletes one or a list of data series value pairs from the data series and directly from the database.
Query() Queries the database and fill the data series according to the result of the query.
SetData() Sets a list of data series value pairs to the data series. This won’t update the database.
GetFlagInfo() Gets the of quality flag information for the data series values.

A user can use these properties and methods to work with the IDataSeries object. The A walk through – creating a time series section uses the above properties to set the time series properties and uses some of the methods listed in Table 10 to set data to the time series. In that part, the SetData method is used. This method only changes the data of a time series in the cache. So, the Add(IDataSeries entity) method of the TimeSeriesList class is used later to save the data to the database. The following listing introduces another way to set the data to a time series.

Listing 25 Using the Add method to update the data of a time series

Notes:

  1. First add the newly created time series to the database. The time series has no data.

  2. Then add the list of data series value pairs to the time series. This also updates the database.

IDataSeriesValuePair and IDataSeriesMemberList interfaces appear as parameters in some of the above methods. The following section will introduce these interfaces in detail.

IDataSeriesValuePair interface

The IDataSeriesValuePair interface is an interface for a data series value. Table 11 lists its properties and methods.

Table 11 Properties and methods in the IDataSeriesValuePair interface

Property/Method Description
Xvalue Value on the X (time) axis.
Yvalue Value on the Y axis.
FlagValue Value of the associated quality flag.
SetYValue(object value) Sets the value on the Y axis in a type safe way.

The following listing shows how to use the above properties and methods to create a new instance of a data series value pair.

Listing 26 Create a new instance of the data series value pair

Notes:

  1. Create a new instance of the IDataSeriesValuePair.

  2. Set the X value.

  3. Set the Y value.

IDataSeriesMember and IDataSeriesMemberList interface

As mentioned before, IDataSeriesMember is an interface for a single member of a time series. The IDataSeriesMemberList interface is an interface for the list of IDataSeriesMember’s. A regular time series has only one member, while an ensemble time series has multiple members.

The following tables list the properties and methods in the IDataSeriesMember and IDataSeriesMemberList.

Table 12 Properties and methods in the IDataSeriesMember interface

Property/Method Description
DataSeries Gets the associated data series.
Sequence Gets the sequence number of the current member.
Statistics Gets the statistics for the current member. This is of type IDataSeriesStatistics which contains the average, maximum, minimum, etc.
This[int index] Gets the data series value pair located at the specified index.
GetValue(DateTime dateTime) Gets the value for the specified date time.
Get(int index) Gets the data series value pair located at the specified index.
GetAll() Reads the data values into memory and get all of the data series value pairs in the cache.
FetchAll() Gets all of the value pairs contained in the current data series member directly from the database.
Fetch(IQuery query) Gets a list of data series value pairs based on a query from the database.
SetValue(IList\<double?> values) Sets member values without updating the database.
Update(IDataSeriesValuePair dataSeriesValuePair) Updates the specified data series value pair in the current member and in the database.
Update(IList\<IDataSeriesValuePair> dataSeriesValuePairList) Updates a list of data series value pairs in the current member and in the database.
CreateDataSeries() Creates a single member data series based on the current member.

Table 13 Properties and methods in the IDataSeriesMemberList interface

Property/Method Description
Count Gets the number of members contained in the data series.
This[int index] Gets the member at the specified index.
CreateNew() Creates a new instance of IDataSeriesMember.
Add(IDataSeriesMember member) Adds a member to the data series and to the database.
Delete(int members) Deletes a specified number of members from the end of the list and from the database.
SetMembers(IList\<IDataSeriesMember members) Sets a list of members to the list without updating the database.

A user can use these properties and methods to work with an ensemble time series. The following listing shows how to create an ensemble time series.

Listing 27 Create an ensemble time series

Notes:

  1. Create a new time series through a fully qualified path.

  2. Create an ensemble time series with two members.

  3. Create a list of data series value pair data.

  4. Set the X value of the ensemble time series. An ensemble time series should only have one time axis. So here the X value is only set one time.

  5. Create a new data series member and set its data values.

  6. Set members to the member list.

  7. Save the newly created ensemble time series to the database.

Since IDataSeries inherits from the IDataSeriesMember interface, a user can also use a list of time series to create one ensemble time series. If a user already has the input list of time series, he can use the CreateEnsemble method in the TimeSeriesList class to create an ensemble time series. The following listing shows the definition of this function.

Listing 28 Definition of the CreateEnsemble method in the TimeSeriesList class

This method only creates an ensemble time series in memory. If a user wants to save the time series to the database, he needs to call the Add method of the TimeSeriesList class.

How to work with Spreadsheet objects

The spreadsheet entity inherits from BaseGroupedEntity which has a GroupId property and implements the ICloneable, ISpreadsheet and IDisposable interfaces. The following diagram shows the relationships:

Figure 4 Spreadsheet UML class diagram

Most of the interfaces can be found in Table 8. BaseGroupedEntity is the base class for an entity belonging to a group. The IDisposable interface defines a method to release an object and its related resources.

The ISpreadsheet interface is the interface for the spreadsheet entity. It defines specific functions of a spreadsheet. Table 14 lists all of the properties and events in the ISpreadsheet interface.

Table 14 Properties and events in the ISpreadsheet interface

Property/Event Description
Id Gets or set the unique identifier for a spreadsheet entity.
ModifiedTime Gets or set the last modified date time of a spreadsheet.
Group Gets or set the parent group of a spreadsheet.
SpreadsheetFeatures Gets or set a list of SpreadsheetFeatureAssociation entities. This stores the association between spreadsheet entities and GIS features.
Workbook Gets the workbook of a spreadsheet.
SpreadSheetSaved The event which is raised after the spreadsheet is saved.
SpreadSheetSaving The event which is raised when the spreadsheet is about to be saved.

A user can set new values to these properties and respond when saving or after saving the spreadsheet using the above events.

In order to work with a spreadsheet entity, assemblies in following table need to be referenced first.

Table 15 Assemblies which need to be referenced to work with spreadsheets

Assembly Description
DHI.Solutions.Application Functionality for logging in to the MIKE OPERATIONS application.
DHI.Solutions.Generic Basic MIKE OPERATIONS framework functionality.
DHI.Solutions.SpreadsheetManager.Interfaces Spreadsheet management interfaces.

The user can use methods in the spreadsheet module or in the SpreadsheetList class to work with a spreadsheet entity. The SpreadsheetList class can be accessed from the spreadsheet module. It can be used to create, get, fetch, add, delete, update, export, and import a spreadsheet. The following listings will give some examples to show how to use methods in the spreadsheet module or SpreadsheetList class to work with a spreadsheet.

Listing 29 shows how to create or get a spread sheet entity.

Listing 29 How to create a new spreadsheet or get a spreadsheet from the database

Notes:

  1. First get the spreadsheet module.

  2. Use the CreateNew() method to create a new spreadsheet without defining its name and parent group.

  3. Define the above spreadsheet’s name and parent group.

  4. Or use CreateNew(string path) to create a new spreadsheet under a specified parent group.

  5. Save the above newly created spreadsheet to the database.

  6. Use Fetch(string path) to get a spreadsheet from the database if the full qualified path of the spreadsheet is available.

  7. Use Fetch(object id) to get a spreadsheet from the database if the ID of the spreadsheet is available.

Listing 30 and Listing 31, respectively, illustrate how to export and import spreadsheets using the SpreadsheetList class.

Listing 30 Export a spreadsheet

Notes:

  1. Use the Export(string path, string fileFullName, bool isOverride) method. The isOverride value indicates whether to overwrite the old spreadsheet if a spreadsheet with same path already exists.

  2. Use the Export(object id, string fileFullName, bool isOverride) method.

  3. Use the Export(ISpreadsheet document, string fileName, bool isOverride) method.

Listing 31 Import a spreadsheet

Notes:

  1. Use the Import(string fileFullName, string path) method. The fileFullName parameter is the full path of a spreadsheet on the disk. The path is the full path in the spreadsheet manager.

  2. Use the Import(string fileFullName, object groupId, string documentName) method. The fileFullName parameter is the same as above. The groupId is the ID of the parent group to import to. The documentName is the name of the imported spreadsheet in the manager.

Listing 32 demonstrates how to open, close, and move a spreadsheet using functions in the spreadsheet module.

Listing 32 Open, close, and move a spreadsheet

Notes:

  1. Use the OpenSpreadsheet(object id) method to open a spreadsheet if its ID is available.

  2. Use the OpenSpreadsheet(string path) method to open a spreadsheet if its full qualified path is available.

  3. Use the OpenSpreadsheet(ISpreadsheet document) method to open a spreadsheet entity.

  4. Use the CloseSpreadsheet(ISpreadsheet document) to close a spreadsheet.

  5. Use the MoveDocument(string path, string groupPath, bool replace) method to move a spreadsheet from one group to another. The path parameter is the full path of the source spreadsheet. The groupPath parameter is the target group path. The replace value indicates whether to replace a spreadsheet with same name in the target group if it already exists.

Business module structure

This section describes the business module of the MIKE OPERATIONS framework in detail.

IModule

The MIKE OPERATIONS framework provides an interface named IModule for the module class. It inherits from the IPlugin interface which is a marker (empty) interface telling the system that a module is a framework plugin. Table 16 shows the properties, events and methods in this interface.

Table 16 The IModule interface

Properties/events/methods Description
Enabled Gets a value indicating whether the module is enabled or not.
Description Gets the description of the module.
Name Gets the name of the module.
StartUp() A method to initialize and start up the module.
ShutDown() A method to shut down the module.
ModuleStarted Event raised when a module has been started.
ModuleShutDown Event raised when a module has been shut down.

Modules in the MIKE OPERATIONS framework follow the “list pattern” by implementing the IListModule interface which inherits from the IModule interface. The following section briefly introduces the IListModule.

IListModule

This interface defines just one method – CreateNewList\<T>. The definition of the method is shown in Listing 33.

Listing 33 Definition of CreateNewList function

This method returns a new instance of one of the supported entity lists in the manager module. The IEntityList\<T> interface in this method is an interface for the entity list class. It provides functionalities to work with an entity. The entity represents a component that contains a specific type of data. It implements the IEntity interface which has an Id property that is the unique identification for an entity. The following sections introduce the IEntity and IEntityList interfaces.

IEntity

The IEntity interface inherits from the INotifyPropertyChanged and INotifyPropertyChanging interfaces. Before a property of an entity is changed, the PropertyChanging event will be raised. After the property value is changed, the PropertyChanged event will be raised. Table 17 lists the main properties and methods defined in this interface.

Table 17 The IEntity interface

Properties/methods Description
Id Gets or sets the value of ID which uniquely identifies an entity.
IsModified Gets a value indicating whether an entity is modified.
Version Gets or sets the version of an entity. This is used to judge whether an entity is the latest one.
UseChangeLog Gets or sets a value indicating whether the change log of an entity needs to be recorded.
SetModified() A method to set the IsModified property.

IEntityList\<T>

T is the generic type of an entity. The IEntityList interface inherits from the IEntityProvider interface which provides methods for getting entities from the data source. Table 18 lists the most commonly used properties and methods of this interface.

Table 18 Properties and methods mostly used in the IEntityList\<T> interface

Properties/methods Description
Count Gets the number of entities in the cached list which contains references to the data that has been loaded.
CurrentQuery Gets the currently used query defining the entities in the list.
this[object id] Gets the entity with a given ID from the cached list.
this[int index] Gets the entity at specified index from the cached list.
Add() A method to add an entity or a list of entities to the database.
Contains() A method to get a value indicating whether an entity is contained in the cached list.
CreateNew() A method to create a new instance of an entity.
Delete() A method to delete an entity or a list of entities from the database.
Fetch() A method to get an entity or a list of entities which match specified conditions directly from the database.
FetchAll() A method to get all entities from the database.
IsCurrent() A method to check whether an entity is the latest version.
AreNotCurrent() A method to return a list of entities which aren’t the latest version.
Query() A method to get entities which match the specified query conditions and cache them in the list.
Update() A method to update an entity or a list of entities in the database.
GetEntityDescriptor() A method to get a descriptor of an entity in the database. The descriptor can be the ID or the path of the entity.

The IEntity and IEntityList are the base interfaces for entities and entity lists. The MIKE OPERATIONS framework also provides specific interfaces for entities with special properties. For example, the INamedEntity is an interface for an entity with a name. The IGroupedEntity is an interface for an entity belonging to a group. The IGroup is an interface for a group entity. These interfaces are useful because many managers organize data in a folder hierarchy.

The MIKE OPERATIONS framework provides a specific entity list interface named IGroupedEntityList for handling the IGroupedEntity. The IGroupedEntityList\<T> is an interface for entity list classes which are associated with any group. It inherits from the IEntityList\<T> interface and has its own methods. Table 19 lists the special methods in the IGroupedEntityList\<T> interface.

Table 19 Special methods in the IGroupedEntityList\<T> interface

Methods Description
CreateNew(string path) A method to create a new entity instance for a given fully qualified path.
Get(string path) Gets an entity with a given fully qualified path from the cached list.
FetchChildren(string groupPath) A method to get all of the child entities under the fully qualified path directly from the database.
GetChildren(string groupPath) A method to get all of the child entities under the specific path from the cached list.

The MIKE OPERATIONS framework provides base entity classes and entity list classes which can simplify the implementation of the above interfaces. The following sections introduce these base classes in brief.

BaseEntity

This class implements the IEntity interface. It is also the base class for the BaseNamedEntity and the BaseGroupedEntity class. In addition, BaseNamedEntity implements the INamedEntity interface. And the BaseGroupedEntity implements the IGroupedEntity interface.

BaseGroup

This class inherits from the BaseNamedEntity class and implements the IGroup interface. The entity shown as a folder in the user interface is a BaseGroup.

Specific entity classes in each manager inherit from the above mentioned base entity classes. In addition, they also implement specific entity interfaces defined in each manager. For example, the time series entity in the Time Series Manager inherits from the BaseGroupedEntity class and also implements the IDataSeries interface which defines special properties and methods for the time series entity. The IDataSeries interface is introduced in the Hints and best practices section above.

BaseEntityList\<Entity>

This class implements the IEntityList\<T> interface. It is also the base class for other special entity list classes like BaseGroupEntityList and BaseGroupedEntityList. Entity is the type of entities which will be handled in this class. User can use methods in this class to add, delete, update, fetch, get, or create an entity and interact with the database.

BaseGroupEntityList\<Group>

This class is responsible for handling group entities which are shown as a folder in the user interface, i.e. the BaseGroup entity. Group is the type of the group entities. It inherits from the above BaseEntityList\<Entity> class and implements the IGroupedEntityList\<T> interface. The functions of the methods in Table 19 for BaseGroupEntityList\<Group> are to create a new group with a given full qualified path, to get a group with a given full qualified path from the cached list, to get all of the child groups under a given parent path directly from the database, and to get all of the child groups under a given path from the cached list.

This class also overrides the GetEntityDescriptor(T entity) method of BaseEntityList. Now the return result of this method is the full path of a group entity. The Fetch(string descriptor) method is also overridden. In order to get a group from the database, the input of the Fetch method needs to be a fully qualified group path.

BaseGroupedEntityList\<Entity, Group>

This class is used to handle grouped entities which are shown as the items under a folder in the user interface. Entity is the type of the grouped entities. Group is the type of the group entities which are shown as the folder. It also inherits from the BaseEntityList\<Entity> class and implements the IGroupedEntityList\<T> interface, so it also implements the methods in Table 19. The functions of these methods for BaseGroupedEntityList\<Entity, Group> are to create a new grouped entity with a given fully qualified path, to get a grouped entity with a given fully qualified path, to get all of the child grouped entities under a given parent path directly from the database, and to get all of the child grouped entities under a specified parent path from the cached list.

The GetEntityDescriptor(T entity) and the Fetch(string descriptor) methods in the BaseEntityList class are also overridden in the BaseGroupedEntityList class. Now the result of GetEntityDescriptor is the fully qualified path of a grouped entity. And the input of the Fetch function needs to be the fully qualified path of a grouped entity instead of the ID.

Specific entity list classes in each manager inherit from the above three base entity list classes – BaseEntityList, BaseGroupEntityList and BaseGroupedEntityList. Besides this, they also implement specific interfaces defined in each manager. Take the Time Series Manager as an example. The TimeSeriesList class inherits the BaseGroupedEntityList class and also needs to implement the ITimeSeriesList interface which is defined in the Time Series Manager and contains special methods to process the IDataSeries object.

Figure 5 shows a UML class diagram depicting the relationship of the above mentioned classes and interfaces.

Figure 5 UML class diagram for classes in module

In summary, an entity is a component holding a specific type of data. An entity list provides methods to manipulate the entity and interact with the database. A module provides access to the entity list and methods to work with the entity. A user can create a new instance of an entity list through the CreateNewList method in the module or directly use the default entity list properties provided by the module, e.g. the time series module has the TimeSeriesList, TimeSeriesGroupList, TimeSeriesFeatureAssociationList and FlagDefinitionList properties which have been introduced in the A walk through – reading a time series section.