Generic Persistent Types

NDO supports generic types in the Professional and Enterprise Editions. With the help of generics you can write the following code:

[NDOPersistent]
public class MyGenericType<T>
{
    T myGenericField;  // persistent field of type T
    ...
}

Heterogeneous Tables

This ability has some consequences for the mapping. The first consequence is related to the type system. .NET treats every concrete type based on MyGenericType as a unique type in the type system:

Debug.Assert(typeof(MyGenericType<int>) != typeof(MyGenericType<double>));

But NDO maps all concrete types (type instances) to one table. This is necessary for several reasons. The main reason is that NDO is not able to determine during compilation, which types will be instantiated. Since NDO maps all type instances to one table, we have to store some information about the concrete type of the stored objects along with the object data so that NDO is able to create an object of correct type during loading. NDO uses an additional string column to store the type information. The column name is defined by the TypeNameColumn element in the mapping file.

<TypeNameColumn>
  <Column Name="NDOTypeName" NetType="System.String,mscorlib" AllowDbNull="False" />
</TypeNameColumn>

Storing Generic Fields

The field myGenericField is of the generic type T. Since NDO doesn't know the type of T, it has to map the field to a general purpose string column. Because of that T must be convertible to a string and vice versa. .NET implements the IConvertible interface for all primitive types so you don't have to bother about type conversions, no matter whether T is a primitive type, a string or a type like Guid or DateTime.

Note that NDO always uses the invariant culture to convert the objects to/from strings.

If you need to use a type, which does not implement the IConvertible interface, you may want to define a TypeConverter for that type. Just mark the type with the attribute

[TypeConverter(typeof(MyTypeConverter))]

There is a sample application in the tutorial folder of your NDO installation. It shows how to store a user defined complex type in a generic field using the TypeConverter approach.

Querying Generic Types

NDO provides two Query classes, a generic (Query) and a non-generic (NDOQuery). For querying generic types you have to use the non-generic query object. This is necessary because the query type has to be the generic type definition instead of a generic type instance:

Query q = pm.NewQuery(typeof(MyGenericType<>), ....);

The generic expression

NDOQuery<MyGenericType<>>

is not valid, since .NET can't instantiate the NDOQuery type using a generic type definition.