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.
- Select the package and set
OrMappingModetoAll. This exposes OR-mapping settings on individual classes. - Select the class.
- Set
PrimaryKeyto the attribute name or names that form the database key. - Set
PrimaryKeyMapperto a named key mapper from theSqlDatabaseConfigof the PersistenceMappers. - Select each attribute used by the primary key and set its
SaveActionto 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:
- Ensure the class has the key attribute. For example, add or retain
SomePKonClass1. - On
Class1, setPrimaryKeytoSomePK. - Set
PrimaryKeyMapperto the mapper appropriate to the database behavior. - On attribute
SomePK, setSaveActiontoFreezeif your application supplies the value, orDBAssignedif the database supplies it. - 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.PrimaryKeytoAlbumId. - Set
Album.PrimaryKeyMappertoAutoInc. - Set
AlbumId.SaveActiontoDBAssigned.
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:
- On class
filmactor, setPrimaryKeytofilm_id,actor_id. - On the single-link end to
film, setColumnNametofilm_id. - On the single-link end to
actor, setColumnNametoactor_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.
