🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Doing your own Primary keys
This page was created by Hans.karlsen on 2019-06-18. Last edited by Wikiadmin on 2026-07-29.

You can configure MDriven primary-key names and key-assignment behavior for a new model or map each class to the keys already used by an existing database.

Choose a primary-key strategy

A primary key uniquely identifies a stored row. MDriven needs both the database column mapping and a strategy for obtaining the key value when an object is saved.

MDriven has two common default naming conventions:

Convention Primary-key column pattern Notes
Legacy Eco_Id The historical MDriven convention.
MDriven <TableName>ID The newer convention. For example, the primary key for table Customer is CustomerID.

The MDriven convention also uses <Name>ID for a single-link column. For example, a link from an Order row to a Customer row can use CustomerID. Names that end in ID make primary keys and foreign keys easier to recognize in reporting tools and when you later reverse engineer a database.

If you use MDriven Framework in Visual Studio, configure the default strategy through a DefaultORMappingBuilder. Assign the same builder to both mapping-provider properties: NewMappingProvider is used when creating or evolving the database, and RunTimeMappingProvider is used while the application runs.

if (rbPMappMDrivenServer.Checked)
{
  if (_ORMappingForMDrivenServer == null)
  {
    _ORMappingForMDrivenServer = new Eco.Persistence.ORMapping.DefaultORMappingBuilder();
    _ORMappingForMDrivenServer.ChildMapRootClass = true;
    _ORMappingForMDrivenServer.DefaultSingleLinkColumnName = "<Name>ID";
    _ORMappingForMDrivenServer.IdColumnName = "<TableName>ID";
  }
  persistenceMapperSqlServer1.RunTimeMappingProvider = _ORMappingForMDrivenServer;
  persistenceMapperSqlServer1.NewMappingProvider = _ORMappingForMDrivenServer;
}

In this example, IdColumnName controls the default primary-key column name and DefaultSingleLinkColumnName controls the default column name for a single link.

Configure a key for one class

Use a class-specific key mapping when the database already has its own key columns, when you reverse engineer a database, or when one class must differ from the default convention.

  1. Select the package and set OrMappingMode to All. This exposes OR-mapping settings on individual classes.
  2. Select the class.
  3. Set PrimaryKey to the attribute name or names that form the database key.
  4. Set PrimaryKeyMapper to a named key mapper from the SqlDatabaseConfig of the PersistenceMappers.
  5. Select each attribute used by the primary key and set its SaveAction to match how the database obtains the value.

The primary-key name must be unique, and the class must contain a corresponding attribute. For example, if the Customer class has an existing integer attribute named CustomerId, set the class PrimaryKey to CustomerId and configure that attribute's save action as described below.

Select the correct PrimaryKeyMapper

PrimaryKeyMapper selects the mechanism that supplies or manages the key. The available named mappers come from PersistenceMappers SqlDatabaseConfig.

Situation PrimaryKeyMapper and SaveAction Example
Default MDriven key handling Use DefaultEcoIdMapper. It creates an integer ID from a common cursor kept in the Eco_id table.
Database assigns an identity/auto-increment value Use an auto-assignment mapper such as AutoInc, and set the key attribute's SaveAction to DBAssigned. A database ArtistId identity column is left unset on insert and read back after the database assigns it.
Application or import supplies the key value Use a mapper that does not auto-assign the value, and set the key attribute's SaveAction to Freeze. An imported SomePK value is retained and cannot change after the first insert.

DBAssigned tells MDriven not to set the key on the initial save and to reread the row after insertion. Use it for database-generated keys. Freeze keeps a supplied key unchanged after the first insert, which is the normal behavior for a primary key that you provide.

Map an existing primary-key attribute

For a class whose modeled attribute is already the database key:

  1. Ensure the class has the key attribute. For example, add or retain SomePK on Class1.
  2. On Class1, set PrimaryKey to SomePK.
  3. Set PrimaryKeyMapper to the mapper appropriate to the database behavior.
  4. On attribute SomePK, set SaveAction to Freeze if your application supplies the value, or DBAssigned if the database supplies it.
  5. Create or evolve the schema only after checking the inheritance mapping described in the next section.

Do not use None when the key must remain stable after the first insert. Choose Freeze for a supplied key.

Account for inheritance and the default root class

A package can have a modeled DefaultSuperClass that all classes inherit from. If it does not, MDriven uses the generated EcoModelRoot in the standard OR mapping.

This matters when a subclass has a custom key. A root class that retains the standard EcoId mapping while a child class uses, for example, SomePK, creates an unsupported and inconsistent mapping.

When the root class should not have a table of its own, configure DefaultORMappingBuilder.ChildMapRootClass as true and assign that builder to both NewMappingProvider and RunTimeMappingProvider. The root is then mapped into child classes. In the code example above, this setting allows Class1 to use SomePK, while a class without special key settings can still receive the default <TableName>ID key.

For the complete custom mapping example, including this inheritance case, see Documentation:Custom OR Mapping.

Use identity keys after reversing a database

When you reverse engineer a database, the reverse process can identify existing key attributes. For integer identity columns, set the class PrimaryKeyMapper to AutoInc and set the key attribute's SaveAction to DBAssigned.

For example, if the database defines AlbumId as an identity column:

  • Set Album.PrimaryKey to AlbumId.
  • Set Album.PrimaryKeyMapper to AutoInc.
  • Set AlbumId.SaveAction to DBAssigned.

If many reversed classes need AutoInc, use the EAL on Documentation:Setting all model classes to use AutoInc as PrimaryKeyMapper rather than editing each class manually.

Define a composite key

A composite key uses two or more columns together to uniquely identify a row. This is common for link tables in reversed databases.

For example, a filmactor table may have no separate ID column, while the combination of film_id and actor_id is unique:

  1. On class filmactor, set PrimaryKey to film_id,actor_id.
  2. On the single-link end to film, set ColumnName to film_id.
  3. On the single-link end to actor, set ColumnName to actor_id.

The comma-separated PrimaryKey tells MDriven that both columns identify the row. The link-end column names must match the existing database columns, so MDriven can resolve each association correctly. See Documentation:Custom OR Mapping for the full reversed-database example.

Check key and association dependencies

A foreign key stores the primary-key value of a related row. When importing several tables, you may need to load key values first and then connect associations in a later step. See Documentation:SQLImport multiple tables with associations for an SQL passthrough example that updates a foreign-key column from a matching business attribute.

When you test inserts into a reversed database, also satisfy any database NOT NULL foreign keys. For example, an Album row cannot be inserted until required Artist and Genre links have values.

See also