Skip to content

MIKE+ DataModule

Introduction

DataModule is used to manpulate data in MIKE+ database. DataTableContainer is the container which contains all the DataTables in MIKE+. DataTable provides a table column interface where all the column (field) related information is accessible. This includes basic column info (title, unit, type) and dynamic eum type information as well as unit conversion APIs.

DataTable VS DataSource

Both DataTable and DataSource can manipulate data in database. But the DataSource is more basic. It only executes pure sql syntax. DataTable has more data logic there. For example, if you just want to change the muid of a link, directly using DataSource is a good choice. But if you want other table fields value change accordingly too, please use DataTable command to update it. It will maintain all related table fields. And license control also happens in DataTable layer.

Examples to create DataTableContainer entity

using DHI.Amelia.DataModule.Interface.Services;
using DHI.Amelia.DataModule.Services.DataTables;
using DHI.Amelia.DataModule.Services.DataSource;
private IDataTableContainer CreateDataTableContainer(string dbOrmuppFile)
{
    // dbOrmuppFile - can be .sqlite file or .mupp file
    var dataSource = BaseDataSource.Create(dbOrmuppFile);
    if (dataSource != null && (dataSource.DbConnection == null || dataSource.DbConnection.State == ConnectionState.Closed))
    {
        dataSource.OpenDatabase();
        if (dataSource != null)
        {
            var dataTables = new DataTableContainer(true) { DataSource = dataSource };
             dataTables.SetActiveModel(dataSource.ActiveModel);
            dataTables.SetEumAppUnitSystem(dataSource.UnitSystemOption);
            dataTables.UndoRedoManager = new AmlUndoRedoManager() { DataTables = dataTables };
            dataTables.OnResetContainer(null, null);

            return dataTables;
        }
    }

    return null;
}
- Important: Please dispose IDataTableContainer when it is not used anymore. Otherwise the memory can't be released. The method is dataTables.Dispose().

Variety of interfaces in DataTable layer

There are a set of data table interfaces for specific purpose, and it is necessary to know all of them which you can convert to for different usage:

  • IMuTable: The most basic and generic interface all data tables will have to implement.
  • MUID: MUID is the primary key for each table row. It's used widely to manipulate data in MIKE+ database.

Table 1: Important methods of IMuTable

Method name Description
CreateRowData Create a new row data entity
SetValue Set a value of row with MUID in COLUMN
SetValues Set values of rows with MUID in COLUMN
Delete Delete a row data
CreateRowData Create a row data
Insert Insert row data
SetValuesByCommand Set a value by command, please check "Data Command" section for detail
DeleteByCommand Delete a row by command, please check "Data Command" section for detail
InsertByCommand Insert a row by command, please check "Data Command" section for detail
GetMuids Get a list of MUIDs is membership of filters and ordered by 'orderBy'.
GetMuidsWhere Get a list of MUIDs with the where filter
GetDouble Get a double from the specified column
GetString Get a string from the specified column
GetInt Get an int from the specified column
GetDateTime Get an int from the specified column
GetMuidAndFieldsWhereOrder Get muids and fields values dictionary
GetMuidDoubleFieldWhereOrder Get muids and double field value dictionary
GetMuidIntFieldWhereOrder Get muids and int field value dictionary
GetMuidStringFieldWhereOrder Get muids and string field value dictionary
GetMuidAndDerivedFieldWhereOrder Get muids and derived field value dictionary

Code example

var dataTables = CreateDataTableContainer(dbOrmuppFile);
// To get all the ids of all the row in LinkTable
var muids = dataTables[DbTableNames.LinkTable].GetMuids(); 
// Get FromNodeID, ToNodeID and Diameter data from LinkTable
IList<string> fieldsToGet = new List<string>() { LinkFields.FromNodeID, LinkFields.ToNodeID, LinkFields.Diameter };
dataTables[DbTableNames.LinkTable].GetMuidAndFieldsWhereOrder(fieldsToGet);
// To update the FromNodeID of "Link_1"
dataTables[DbTableNames.LinkTable].SetValues("Link_1", new Dictionary<string, object>() { { LinkFields.FromNodeID, "Node_1" }}
// To create a new link row data
var linkRow = dataTables[DbTableNames.LinkTable].CreateRowData("Link_2");
linkRow.FromNodeID = "Node_1";
linkRow.ToNodeID = "Node_2";
linkRow.Diameter = 5.0;
// To insert a new link into LinkTable
dataTables[DbTableNames.LinkTable].Insert(linkRow);
// To query the new link row data
var queryLinkRow = dataTables[DbTableNames.LinkTable].Get("Link_2");
// To Delete the new link row from LinkTable
dataTables[DbTableNames.LinkTable].Delete(queryLinkRow);

  • IMuGeomTable: This interface is implemented by all data tables which have geometry columns. All the geometry manipulation methods are exposed by it.

Table 2: Important methods of IMuGeomTable

Method name Description
CreateRowData Create row data with geometry
GetGeometry Get geometry for a given muid
SetGeometry Set geometry for a given muid
GetBoundingBox Get boundary box of this geometry table

Code example

IGeometry geom = ((IMuGeomTable)dataTables[DbTableNames.LinkTable]).GetGeometry("Link_1");
msm_Link linkRow = (IMuGeomTable)dataTables[DbTableNames.LinkTable]).CreateRowData(geom, "Link_2") as msm_Link;
linkRow.TypeNo = (int)msmLink_TypeNo.Circular;
linkRow.Diameter = 2.0;
dataTables[DbTableNames.LinkTable].Insert(linkRow);

  • IMuNodeBasedTable: This interface is implemented by data tables which represent network node element (e.g. node, junction or tank). It has some special method for manipulating the network node, e.g. move node will maintain the network connectivity.

Table 3: Important methods of IMuNodeBasedTable

Method name Description
GetNumberofLinks Get number of links which is connected to a specified node
GetNumOfLinksEnabled Get number of enabled links which is connected to a specified node
GetDownstreamLinks Get downstream link muids which is connected to a specified node
GetUpstreamLinks Get upstream link muids which is connected to a specified node
MoveNodeWithFromToAssociations All the node and links associatsions will be updated here
  • IMulinkBasedTable: This interface is implemented by data tables which represent network link element with from/to Node (e.g. link, pipe, pump etc.). It has some special method for manipulating the network link element. E.g. edit link will maintain the network connectivity.

  • IConnectLineTable: This interface is implemented by data tables which represent connection line between network elements and source elements (e.g. load point, demand allocation). It has special properties and method to manipulate connection line to maintain the connectivity.

DataTables and Fields

There are three modules in MIKE+. They are "Rivers, collection system and overland flows", "SWMM5 collection system and overland flows" and "Water distribution". Each of the modules has its own set of tables. But they also share some tables which are system tables. MIKE+ has its table naming rules. You can use DHI.Amelia.GlobalUtility.Constants.DbTablesAndFields.DbTableNames to access all the MIKE+ table names.

Table 4: DataTable naming rules

table name prefix Description
m_ System table which are shared among modules, e.g. m_ModelSetting saved the model setting info for each of the modules
msm_ table belongs to CS, e.g. msm_Pump is the pump in CS network
mrm_ table belongs to river module, e.g. mrm_Pump is the pump on river
m2d_ table belongs 2D overland module, m2d_Boundary is the 2d boundary table
mw_ table belongs to WD, e.g. mw_Pump is the pump in WD network
mss_ table belongs to SWMM, e.g. mss_Pump is the pump in SWMM network

Each dataTable has its data table field class. Please use DHI.Amelia.GlobalUtility.Constants.DbTablesAndFields to find all the fields class. The naming rules is the same as DataTable name. For example, mw_PumpFields is the fields class for mw_Pump, mrm_PumpFields is the fields class for mrm_Pump. The only difference is there is no "msm_" prefix for CS table fields class; PumpFields is the fields class for msm_Pump. You can use IDataTableContainer.GetAllDefaultFieldsInfo method to get the field information. It inlcudes field name, field data type. It also includes the eumItem and unit info if it is a double field.

Code example

var dataTables = CreateDataTableContainer(dbOrmuppFile);
var muidFieldInfoDict = dataTables.GetAllDefaultFieldsInfo(DbTableNames.LinkTable);

Domain field

Domain field is a field which has domain meaning. It is a integer type field. Please check DHI.Amelia.GlobalUtility.DomainOptions class for mapping the integer value between domain type.

Domain eum type in DHI.Amelia.GlobalUtility.DomainOptions

public enum msmLink_TypeNo
{
    Undefined = -1,
    Circular = 1,
    CRS,
    Rectangular,
    O_Shape,
    Egg_Shape,
    Natural_Channel,
    Simple_Routing
}

DataModule DataTable: Data Command

This section describes the basic introduction and design principle of MIKE+ data command. To help developers have a basic understanding of how MIKE+ data command works and how to use it in the project. The data command in MIKE+ is the core feature for data update in DataModule. It directly builds upon DataSource and DataTable layer and it mainly solves the two problems:

  • Support undo/redo operation: Lot of data editing operations in MIKE+ is complex and therefore need to have a possibility to roll back the changes if users make any mistake. Current undo/redo mechanism in MIKE+ is based on command pattern. E.g. package a logically related data and operation together into a command.

  • Support on the fly transaction: In order to make the command execution easy to use and flexible, we introduced a command group concept to support a set of command to be treated as a transaction.

  • Enhance data update integrity: The most important data in MIKE+ are all in database, and we must maintain the data integrity during the data update if something goes wrong or exceptions happen. Command is an atom of a set of operations which must maintain the ALL or NOTTHING principle. So, use command will handle this automatically on the fly.

Table 5: Important Db command in DataTables

Command method Description
SetValueByCommand Update field value for a specified id
SetValuesByCommand Update several field values for a specified id
InsertByCommand Insert a row into a specified table
DeleteByCommand Delete a row for a specified table
MultiDeleteByCommand Delete several rows at a time for a specified table
UpdateGeomByCommand Update the geometry for a table which is BaseTableGeometry

Examples to get active module

var dataTables = CreateDataTableContainer(dbOrmuppFile);
var activeModule = dataTables.ActiveModel;

Examples to query data, modify data and delete data inside IDataTableContainer by using DbCommand

var dataTables = CreateDataTableContainer(dbOrmuppFile);
// To get all the ids of all the row in LinkTable
var muids = dataTables[DbTableNames.LinkTable].GetMuids(); 
// Get FromNodeID, ToNodeID and Diameter data from LinkTable
IList<string> fieldsToGet = new List<string>() { LinkFields.FromNodeID, LinkFields.ToNodeID, LinkFields.Diameter };
dataTables[DbTableNames.LinkTable].GetMuidAndFieldsWhereOrder(fieldsToGet);
// To set the FromNodeID of "Link_1"
var cmdResult = dataTables[DbTableNames.LinkTable].SetValuesByCommand("Link_1", new Dictionary<string, object>() { { LinkFields.FromNodeID, "Node_1" }}
// To insert a new link into LinkTable, the geometry is null
dataTables[DbTableNames.LinkTable].InsertByCommand(ref "Link_2", null, new Dictionary<string, object>() { { LinkFields.FromNodeID, "Node_1" }, { LinkFields.ToNodeID, "Node_2" }, { LinkFields.Diameter, 5.0 }});
// To Delete a link from LinkTable
dataTables[DbTableNames.LinkTable].DeleteByCommand("Link_2");
Table 6 Assemblies which need to be referenced by using DataTableContainer

Assembly
DHI.Amelia.DataModule.Interface
DHI.Amelia.DataModuleDHI.Amelia.DataModule
DHI.Amelia.GlobalUtility
DHI.Amelia.Infrastructure.Interface
DHI.Amelia.ProjectLoaderPFS.Interface
DHI.Tracing