You can map an individual attribute with a non-standard persistence mapper when you must match an existing database schema; this page is for developers who need that specialization, especially when querying integer-backed enumerations.
When to use an attribute-specific mapper
A persistence mapper defines how a modeled value is stored in and read from the database. MDriven's standard mapping for an enumeration stores its text representation. A legacy database may instead store the enumeration as an integer.
Use an attribute-level override when the database column requires a representation that differs from MDriven's standard representation. For example, if Class1.MyEnumAttribute is stored as an integer column, you can assign Eco.Persistence.Default.GenericEnumAsInteger to that attribute.
Do this only when you need to integrate with an existing schema or meet another explicit storage requirement. Non-standard mapper choices can prevent generic tools that depend on MDriven's standard mapping from functioning correctly, including MDriven Prototyping and MDrivenServer.
For general background on persistence mappers and object-relational mapping, see Documentation:Persistence mappers, Documentation:Persistence, and Documentation:OR Mapping. For broader attribute conversion guidance, see Documentation:Attribute or Data Type Conversion.
The enum query-parameter issue
An attribute override controls how that attribute is mapped. A query parameter is different: when MDriven translates a query, it has the parameter value but does not have the attribute available when selecting the mapper for that parameter.
This distinction matters when the database stores an enum as an integer. Consider this query:
MyEnumType eTest = MyEnumType.theFirstValue;
IList<Class1> result =
(from x in ecoSpace.PSQuery<Class1>()
where x.MyEnumAttribute == eTest
select x).ToList();
If MyEnumAttribute uses GenericEnumAsInteger, but the query parameter is still mapped with the standard enum-as-text mapper, the generated comparison mixes an integer database value with an nvarchar parameter. SQL Server can then report an error such as:
Error converting a nvarchar value to int.
Using GenericEnumAsVar or running a memory query may appear to work because those paths do not expose the same database parameter-mapping mismatch. They do not correct the configuration for a persistent query.
How MDriven selects a mapper for an enum parameter
When MDriven maps a query parameter, it uses the following lookup order:
- It looks for a persistence mapper whose name is the parameter type's full name. For
MyEnumTypein theEcoProject1namespace, the name isEcoProject1.MyEnumType. - If no mapper with that name exists and the parameter is an enum, it looks for a mapper named
Enum.
The mapper configured on the attribute is therefore not automatically used for eTest in the example query.
| Situation | Attribute mapping | Parameter mapper MDriven looks for |
|---|---|---|
A mapper is named EcoProject1.MyEnumType
|
The attribute can use an integer enum mapper. | EcoProject1.MyEnumType
|
| No type-specific mapper exists and the parameter is an enum | The attribute can use an integer enum mapper. | Enum
|
Configure integer-backed enum queries
Configure the parameter mapper to match the database representation used by the enum attribute. Choose one of the following approaches.
Use this option when enum values in the relevant persistence configuration should generally be stored and queried as integers.
- Find the persistence-mapper collection used by the persistence configuration.
- Locate the mapper named
Enum. - Set its
MapperTypeNametoEco.Persistence.Default.GenericEnumAsInteger. - Re-run the persistent query.
With this configuration, an enum parameter for which no type-specific mapper exists is mapped as an integer.
Option 2: Add a mapper for one enum type
Use this option when only one enum type, or a selected set of enum types, is integer-backed. It avoids changing the fallback behavior for every enum.
- Find the persistence-mapper collection used by the persistence configuration.
- Add a mapper entry.
- Set the mapper name to the enum type's full name. For this example, use
EcoProject1.MyEnumType. - Set
MapperTypeNametoEco.Persistence.Default.GenericEnumAsInteger. - Keep or set the attribute's mapper to the integer enum mapper so that the column and query parameter use the same representation.
- Re-run the query.
After either configuration, both sides of this predicate use the integer representation:
MyEnumType eTest = MyEnumType.theFirstValue;
IList<Class1> result =
(from x in ecoSpace.PSQuery<Class1>()
where x.MyEnumAttribute == eTest
select x).ToList();
Choose the narrowest scope
Use a type-specific mapper when a legacy schema mixes enum storage conventions. For example, if EcoProject1.OrderStatus is stored as an integer but EcoProject1.CountryCode uses MDriven's standard text representation, add a mapper named EcoProject1.OrderStatus rather than changing the shared Enum mapper.
Change the shared Enum mapper only when integer storage is the intended default for enum parameters in that persistence configuration.
Verify the complete mapping
Before relying on a persistent query, verify all of the following:
- The database column type matches the selected attribute mapper. An integer-backed enum attribute requires an integer-compatible column.
- The attribute uses the mapper required by that column.
- The query parameter resolves to the same representation through either its type-specific mapper or the
Enumfallback mapper. - Persistent queries are tested against the target database. A memory query does not prove that SQL parameter mapping is correct.
- You understand the impact on tools that expect MDriven's standard persistence mapping.
If you are adapting a legacy database, use HowTos:Reverse Engineer a Database for the schema-to-model workflow. For primary-key and other custom object-relational mapping concerns, see Documentation:Doing your own Primary keys and Documentation:Custom OR Mapping.
