When instances of a compile time data type (.NET classes excluding EPiServer.Data.Dynamic.PropertyBag and classes implementing System.IEnumerable) are saved in the Dynamic Data Store, their “inline” properties are mapped to columns in the “big table”. This is known logically as a store.
The default algorithm for mapping .NET classes (excluding EPiServer.Data.Dynamic.PropertyBag and classes implementing System.IEnumerable) to a store is as follows:
You can override the default mapping behavior. This is useful if you do not want certain public properties to be mapped or do want certain non-public properties to be mapped.
To use custom mapping, you need to add the System.Runtime.Serialization.DataContactAttribute to your class definition. In this case, only properties marked with the System.Runtime.Serialization.DataMemberAttribute will be mapped and saved in the Dynamic Data Store regardless of the accessibility status. They must still however have both a getter and setter.
See the MappingWithDataContract class in the DDS sample project for examples.
You may want to save an object of an existing class that has already been marked with DataContactAttribute and its member properties with DataMemberAttribute. One problem might be that the use of these properties does not match the desired behavior when an object instance is saved in the Dynamic Data Store. In these cases, you can also add the EPiServerDataContractAttribute to the class definition and EPiServerDataMemberAttribute to the properties to be saved. The Dynamic Data Store will use these attributes in preference to the Microsoft ones to resolve the conflict.
See the MappingWithEPiServerDataContract class in the DDS sample project for examples.
Some classes in the .NET Framework do not have properties that the Dynamic Data Store can use to extract the value, save to the database and then re-inflate an instance with the value from the database. If you want to use such a type as a property on a class that will be saved to the Dynamic Data Store, you need to register a Type Handler for it.
A good example of this is the System.Uri class. This class only has read-only properties and therefore saving an instance to the Dynamic Data Store without a Type Handler is meaningless as no data will be stored for it.
See the MappingWithTypeHandler class in the DDS sample project for examples.
Properties saved using PropertyBags are mapped as if the properties were public members properties on a normal .NET class. PropertyBags can be mapped in the following ways:
See the ImplicitDynamicMapping and ExplicitDynamicMapping classes in the DDS sample project for examples.
From time to time you may need to change the structure of your data. This can mean adding, removing or changing properties on your .NET classes or PropertyBags.
The Dynamic Data Store is quite flexible when it comes to accepting changes to types that have been saved in a store.
You can remap .NET classes to stores in the following ways:
A .NET class whose instances will be saved in the Dynamic Data Store can be optionally decorated with the EPiServerDataStoreAttribute. In these cases, set the AutomaticallyRemapStore property to true. When the Episerver application starts, it scans for all classes with this attribute and automatically remaps the .NET class to the store, if needed. Any properties that have been renamed MUST be marked with the EPiServerDataPropertyRenameAttribute attribute, otherwise the remap treats them as if one property was removed (with the old name) and one added (with the new name).
To remap a store, obtain the store definition of a store either via the StoreDefinition property of a DynamicDataStore instance or via the StoreDefinition.Get method. You can then call the Rename and Remap methods to update the store's mappings. Note that you should call Rename before Remap, otherwise properties that have been renamed in the data type are treated as if one property has been removed and one added. Finally, call the CommitChanges method of StoreDefinition to update the store's meta information in the database. If a DynamicDataStore instance reference is held, then its Refresh method should be called to align its in-memory copy of the store definition with the one committed to disk.
These rules are followed when remapping stores:
See the StoreReMapping class for examples of store re-mapping and the PropertyReName class for how to update mappings when a property has been renamed on a type, both in the Dynamic Data Store SDK.
It can be convenient to save instances of a Type in the same store, regardless of where those instances are in an object graph. You have the following options:
Result: The top level Person is saved in the “MyPeople” store but all other instances of the Person Type in the object graph are saved in the “People” store (because of the global mapping).
In order to adhere to the global Type to Store mappings you should create or obtain your top level store by calling DynamicDataStoreFactory.Create or GetStore with just the type and not a store name.
See the UsingGlobalTypeToStoreMapping and UsingLocalTypeToStoreMapping classes in the DDS sample project for more details.
In the same way as it may be convenient to map a Type to a Store, it may also prove convenient to map a store to a custom big table. See the Big Table section in the Dynamic Data Store topic for more details.
The UsingGlobalStoreToTableMapping class in the DDS sample project demonstrates this technique.
Last updated: Oct 27, 2016