🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Working with Code and Persistence Mapping
This page was created by Alexandra on 2018-12-02. Last edited by Wikiadmin on 2026-07-29.

You can configure how an MDriven model maps to SQL database tables, keys, foreign-key columns, and inheritance when the default persistence mapping does not match the database structure you need.

This page covers SQL database persistence mapping in MDriven. It does not apply to systems using XML persistence mappers. MDrivenServer uses the settings described here as its defaults.

Start with the model, not mapping XML

Object-relational mapping (OR mapping) translates classes and attributes in your model to database tables and columns. MDriven normally calculates this mapping from the model when you evolve the database. You only need to change mapping configuration when the generated defaults do not meet your requirements.

For example, you may want these conventions:

  • A shared abstract superclass has no table of its own.
  • Attributes inherited from that superclass are stored in each concrete child table.
  • Identity columns use names such as Class1ID instead of the default Eco_Id.
  • Foreign-key columns end in ID.

Do not normally generate and maintain mapping XML by hand. During database evolution, MDriven compares the mapping stored for the existing database with a newly calculated mapping. That comparison lets MDriven determine the database changes required by model changes.

For background on persistence mapper choices, see Documentation:Persistence mappers. For the broader persistence concepts, see Documentation:Persistence.

Configure child-mapped inheritance

A child-mapped class has no table of its own. Its persistent attributes are instead included in the tables of its child classes. This is useful for an abstract superclass that supplies common attributes to concrete classes.

Consider this inheritance structure:

  • TheDefaultSuperClass is abstract and provides CreateTime and ChangeTime.
  • Class1 inherits from TheDefaultSuperClass and adds Attribute1.
  • Class2 inherits from Class1 and adds Attribute2.
  • Class3 is abstract and inherits from TheDefaultSuperClass.
  • Class4 inherits from Class3 and has Attribute1 and Attribute2.

If TheDefaultSuperClass and Class3 are abstract and child-mapped, neither needs a database table. The concrete tables contain the inherited columns required by their mapped class:

Model class Table produced Example columns
TheDefaultSuperClass (abstract, child-mapped) No table Its attributes are included in concrete child tables.
Class1 Class1 Class1ID, ECO_TYPE, CreateTime, ChangeTime, Attribute1
Class2 Class2 Class2ID, ECO_TYPE, Attribute2
Class3 (abstract, child-mapped) No table Its inherited attributes are included in Class4.
Class4 Class4 Class4ID, ECO_TYPE, CreateTime, ChangeTime, Attribute1, Attribute2

The mapping uses an identity key and a discriminator. In the generated mapping, an alias identifies the table used by a class, the key implementation identifies its key column, and the discriminator identifies the class type. The following shortened example shows the structure for Class1:

<ClassDef Name="Class1" SuperClass="TheDefaultSuperClass">
  <AliasDef Name="Class1_A" Table="Class1" ExtentRequiresDiscriminator="False">
    <KeyImpl Name="EcoKey">
      <KeyColumn Name="Class1ID" />
    </KeyImpl>
    <DiscriminatorImpl Name="EcoType" Column="ECO_TYPE" />
  </AliasDef>
  <DiscriminatorValue Name="EcoType" Value="3" />
  <AttributeDef Name="ChangeTime" Alias="Class1_A" Columns="ChangeTime" AttributeMapper="&lt;Default&gt;" />
  <AttributeDef Name="CreateTime" Alias="Class1_A" Columns="CreateTime" AttributeMapper="&lt;Default&gt;" />
  <AttributeDef Name="Attribute1" Alias="Class1_A" Columns="Attribute1" AttributeMapper="&lt;Default&gt;" />
</ClassDef>

Set up the mapping providers

Use a DefaultORMappingBuilder component in the PMP designer to calculate a mapping from the current model and to select the mapping used at runtime.

  1. Add a DefaultORMappingBuilder component to the PMP designer.
  2. Set NewMappingProvider to DefaultORMappingBuilder1, or to the instance name of the builder you added.
  3. Set RunTimeMappingProvider to the mapping provider that the application must use when it accesses the database.
  4. Configure the builder and the relevant package or classes as described in the following sections.
  5. Generate code and build the project.
  6. Switch to the PMP view, select Validate Model, and then select Generate default mapping XML if you need to inspect the calculated mapping.

Know what each provider does

Provider Purpose Example use
NewMappingProvider Describes the mapping calculated from the current model after a database evolution. You add Attribute2 to Class2; this provider describes the new Attribute2 column.
OldMappingProvider Describes the mapping currently represented by the database. MDriven uses it with the new mapping to identify what must change in an existing database.
RunTimeMappingProvider Supplies the mapping used while the application reads and writes the database. At runtime, Class1.Attribute1 is read from or written to the configured Class1 table column.

Configure the default superclass at package level

Set the package so that TheDefaultSuperClass is the default superclass for the other classes in that package. Mark TheDefaultSuperClass as abstract; abstract classes are shown in italic in diagrams.

Then configure that default superclass as child-mapped in DefaultORMappingBuilder. This prevents a separate table for the abstract default superclass and places its attributes in the child tables instead.

For the example above, CreateTime and ChangeTime appear in Class1 and Class4, because those are the concrete mapped classes that inherit them. They do not require a TheDefaultSuperClass table.

Configure names for keys and foreign keys

The default builder also controls naming conventions. Set these conventions when the generated names must be easier to recognize in the database or must align with an existing convention.

What you configure Default described by this page Example alternative Result
Foreign-key column naming <Name> Append ID A reference named Customer can use a column ending in ID.
Identity-column naming Eco_Id <TableName>ID The Class1 table uses Class1ID; the Class4 table uses Class4ID.

These conventions make database keys easier to identify when you inspect the schema directly: joinable identity and foreign-key columns consistently end in ID.

Configure mapping for an ordinary class

You can configure OR mapping for an individual, non-default-superclass class in that class's properties.

If the mapping property is not visible on a class, set the package's OrMappingConfigMode setting first. This enables the class-level OR mapping configuration.

Use class-level configuration when one class needs a mapping rule that differs from the package-level default. For example, retain the package convention for most classes while configuring a specific class to use a particular mapping behavior.

Inspect generated mapping XML when diagnosing mapping

Generating default mapping XML is primarily a diagnostic and learning tool. It appends an XML file to the project so that you can see the mapping MDriven calculated from the model and configuration.

A generated mapping contains both:

  • Class mapping definitions, including aliases, keys, discriminators, and attribute-to-column mappings.
  • Database table definitions, including columns and indexes.

For example, a concrete Class1 definition can declare Class1ID as its key column, map the discriminator to ECO_TYPE, and map Attribute1 to the Attribute1 column. Its table definition then includes those columns and a primary-key index on Class1ID.

Do not treat this generated XML as the normal place to make model changes. Change the model and mapping configuration, then let MDriven calculate the updated mapping for database evolution.

Work with an existing database

When mapping must match an existing database, OR mapping can be customized beyond the defaults described here. You can also reverse derive a model from a database. Database schema alone may not contain every association or key detail needed for a complete model, so review and supplement the result where necessary.

See HowTos:Reverse Engineer a Database for the reverse workflow and for adding missing primary-key, attribute, and association information.

Map special attribute types

The model's attribute type must resolve to an available .NET type when MDriven builds the runtime model and derives code. MDriven resolves type names through EcoDataTypes.xml; if it cannot find a definition for a common type name, it treats that type as String.

A persistence mapper defines how a .NET type is handled by the database for inserts, updates, deletes, and selects. You can assign a mapper at the attribute level through the attribute's PersistenceMapper property, or configure a mapper for a common name or .NET type before the EcoSpace starts. See Documentation:Type mapping, OR-Mapping for the type-resolution and custom-mapper details.

For database-generated GUID values, see Documentation:Autoguid.

See also