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;
}
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");
| Assembly |
|---|
| DHI.Amelia.DataModule.Interface |
| DHI.Amelia.DataModuleDHI.Amelia.DataModule |
| DHI.Amelia.GlobalUtility |
| DHI.Amelia.Infrastructure.Interface |
| DHI.Amelia.ProjectLoaderPFS.Interface |
| DHI.Tracing |