You can define model-friendly attribute type names and control how those types are represented in an SQL database; this page is for developers extending type resolution or assigning a custom persistence mapper.
Overview
In MDriven, an attribute type written in the model is a common name. A common name is resolved to an available .NET type when ECO creates the runtime model and when code is derived from the model.
For example, you can model an attribute as Text or CrazyType rather than entering a fully qualified .NET type name in every model attribute. The type definition tells ECO which .NET type that common name represents. A persistence mapper then determines how that .NET type is read from and written to the database.
| Term | Meaning | Example |
|---|---|---|
| Common name | The type name used on a modeled attribute. | Text
|
| Canonical name | The name that identifies a type definition in EcoDataTypes.xml.
|
ClassLibrary1.CrazyType
|
| .NET type | The runtime type that ECO and derived code must be able to load. | ClassLibrary1.CrazyType, ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5348474bcfb2dae2
|
| Persistence mapper (PMapper) | The component that defines how a .NET type is handled for database inserts, updates, deletes, and selects. | StringAsText
|
Map a common name to a .NET type
Define the mapping in EcoDataTypes.xml.
- For ECO, the file is in
<installdir>/Config/. - For AppComplete, the file is in the application's
binfolder.
The referenced class library must be loadable from the supplied type description. In particular, ECO may require the class library to be installed in the GAC because Visual Studio's assembly-loading location for non-GAC assemblies is not predictable.
Example: add a custom value type
The following definition lets a modeled attribute use either CrazyType or ClassLibrary1.CrazyType as its common name. Both resolve to the same .NET type.
<Type CanonicalName="ClassLibrary1.CrazyType"
Type="ClassLibrary1.CrazyType, ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5348474bcfb2dae2">
<CommonName Name="CrazyType" CaseSensitive="false"/>
<CommonName Name="ClassLibrary1.CrazyType" CaseSensitive="false"/>
<LanguageName Language="C#" Name="ClassLibrary1.CrazyType"/>
<LanguageName Language="Delphi" Name="ClassLibrary1.CrazyType"/>
<LanguageName Language="Oxygene" Name="ClassLibrary1.CrazyType"/>
<LanguageName Language="VB" Name="ClassLibrary1.CrazyType"/>
</Type>
CaseSensitive="false" means that ECO does not require an exact letter case for that common name.
Important: an unresolved common name becomes String
If ECO cannot find a definition in EcoDataTypes.xml for a common name, it treats the attribute as String. It does not report an error for this fallback.
For example, if an attribute is modeled as CrazyType but its CommonName entry is missing or cannot be loaded, ECO handles it as a string. Verify the type definition and assembly availability before relying on a custom type.
Assign a persistence mapper
A persistence mapper defines how a real .NET type is handled by the database, including inserts, updates, deletes, and selects. To create a custom mapper, implement IGenericSingleColumnAttributemapping.
Register the mapper with SetPMapper before the EcoSpace starts. Registering it after startup is too late because the runtime model has already been prepared.
PersistenceMapperXXX.SqlDatabaseConfig.SetPMapper(
"CommonName",
typeof(YourPMapper));
The registration key can identify more than a common name. ECO can resolve a mapper from:
- A common name, such as
Text. - A specific modeled attribute, using
Class.Attribute. - A .NET type.
For example, this registration replaces the mapper selected for System.Int:
PersistenceMapperXXX.SqlDatabaseConfig.SetPMapper(
"System.Int",
typeof(YourPMapper));
Use a type-wide registration only when every attribute of that type should use the replacement behavior. Use an attribute-specific mapper selection when one attribute has different storage requirements.
Choose the mapper on a modeled attribute
Each modeled attribute has a PersistenceMapper property. If you cannot see this property in MDriven Designer, select the package and set ORMappingConfigMode to Medium or All.
The recommended setting is <Default>. With this setting, ECO first resolves the attribute's common name to a .NET type and then finds the persistence mapper registered for that type.
Attribute PersistenceMapper value
|
Result | Use it when |
|---|---|---|
<Default>
|
ECO resolves the common name to its .NET type and selects the mapper for that type. A tagged value in the type definition can replace this default. | The normal mapping is appropriate. |
| A registered mapper name | ECO uses that mapper for the attribute, even if another mapper is the default for its resolved .NET type. | One attribute needs special database handling. |
For example, an attribute whose common name resolves to System.String normally uses the mapper selected for that .NET type. If the attribute's PersistenceMapper property names a custom mapper, that attribute uses the custom mapper instead.
Set mapper defaults in EcoDataTypes.xml
A type definition can supply tagged values to the runtime model. This allows a common name to select a mapper while the model attribute remains set to <Default>.
The following example defines Text as System.String. It assigns the StringAsText mapper and sets Eco.Length to -1 for attributes using this type.
<Type CanonicalName="Text" Type="System.String">
<CommonName Name="text" CaseSensitive="false"/>
<CommonName Name="memo" CaseSensitive="false"/>
<LanguageName Language="C#" Name="string"/>
<LanguageName Language="Delphi" Name="string"/>
<LanguageName Language="Oxygene" Name="string"/>
<LanguageName Language="VB" Name="String"/>
<TaggedValue Tag="Eco.PMapper" Value="StringAsText"/>
<TaggedValue Tag="Eco.Length" Value="-1"/>
</Type>
With this definition, an attribute modeled with common name Text can retain PersistenceMapper = <Default>. The type definition replaces that default with StringAsText at runtime.
A complete selection example
Assume a model contains Document.Body with the attribute type Text.
- ECO finds
TextinEcoDataTypes.xml. - The type definition resolves
TexttoSystem.String. - The attribute has
PersistenceMapper = <Default>. - The
Eco.PMappertagged value in the type definition selectsStringAsText. - ECO uses
StringAsTextwhen it persistsDocument.Body.
If Document.Body instead names a registered mapper directly in its PersistenceMapper property, ECO uses that named mapper for this attribute.
This page covers the type-to-.NET-type and type-to-persistence-mapper selection path. OR mapping is the broader process of representing modeled objects in relational storage. For SQL database mapping configuration, generated mapping XML, runtime mapping providers, inheritance mapping, and database naming settings, see Documentation:Working with Code and Persistence Mapping.
Use Documentation:Custom OR Mapping when you need to adjust the generated relational mapping rather than select a mapper for an attribute type. For the built-in simple attribute types, including String, Text, Double, Decimal, Integer, DateTime, Boolean, Blob, and Guid, see Documentation:Autoguid.
