Exam Area: Content Area 3 – Website Implementation & Delivery (25%)
Reference: https://docs.developers.optimizely.com/content-management-system/docs/dynamic-data-store
Dynamic Data Store (DDS) is a mechanism for storing custom data in the CMS database without needing to create custom SQL tables.
using EPiServer.Data;
using EPiServer.Data.Dynamic;
// POCO class to store in DDS
[EPiServerDataStore(AutomaticallyRemapStore = true)]
[EPiServerDataTable(TableName = "tblMyData")] // Optional
public class MySettings
{
[EPiServerDataIndex]
public Identity Id { get; set; } // DDS Identity (required)
public string Name { get; set; }
public int Value { get; set; }
public DateTime CreatedDate { get; set; }
public bool IsActive { get; set; }
}
using EPiServer.Data.Dynamic;
public class MySettingsService
{
private readonly DynamicDataStore _store;
public MySettingsService()
{
_store = typeof(MySettings).GetOrCreateStore();
}
// CREATE
public void Save(MySettings settings)
{
if (Identity.IsNullOrEmpty(settings.Id))
{
settings.Id = Identity.NewIdentity();
}
_store.Save(settings);
}
// READ - Single
public MySettings GetById(Identity id)
{
return _store.Load<MySettings>(id);
}
// READ - All
public IEnumerable<MySettings> GetAll()
{
return _store.LoadAll<MySettings>();
}
// READ - By condition
public MySettings GetByName(string name)
{
return _store.Find<MySettings>("Name", name).FirstOrDefault();
}
// LINQ support
public IEnumerable<MySettings> GetActive()
{
return _store.Items<MySettings>()
.Where(s => s.IsActive)
.ToList();
}
// UPDATE
public void Update(MySettings settings)
{
_store.Save(settings); // Save also updates if an Id exists
}
// DELETE
public void Delete(Identity id)
{
_store.Delete(id);
}
// DELETE - By object
public void Delete(MySettings settings)
{
_store.Delete(settings);
}
}
public class MySettingsService
{
private readonly DynamicDataStoreFactory _storeFactory;
public MySettingsService(DynamicDataStoreFactory storeFactory)
{
_storeFactory = storeFactory;
}
private DynamicDataStore Store => _storeFactory.GetStore(typeof(MySettings))
?? _storeFactory.CreateStore(typeof(MySettings));
public MySettings GetSettings()
{
return Store.LoadAll<MySettings>().FirstOrDefault();
}
}
// Identity is the ID type used in DDS
Identity id = Identity.NewIdentity(); // Create new
Identity id2 = Identity.NewIdentity(Guid.NewGuid()); // From GUID
bool isEmpty = Identity.IsNullOrEmpty(id);
// Compare
bool equal = id.Equals(id2);
string str = id.ToString(); // GUID string
// Add indexes to speed up queries
[EPiServerDataStore]
public class UserPreference
{
[EPiServerDataIndex]
public Identity Id { get; set; }
[EPiServerDataIndex] // Index on this field
public string UserId { get; set; }
public string PreferenceKey { get; set; }
public string PreferenceValue { get; set; }
}
In addition to DDS, you can create custom tables:
// Use IInitializableModule to create a table
[InitializableModule]
[ModuleDependency(typeof(EPiServer.Data.DataInitialization))]
public class CustomTableInitialization : IInitializableModule
{
private readonly IDatabaseHandler _databaseHandler;
public void Initialize(InitializationEngine context)
{
CreateCustomTable();
}
private void CreateCustomTable()
{
const string sql = @"
IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'tblCustom')
BEGIN
CREATE TABLE tblCustom (
Id INT IDENTITY(1,1) PRIMARY KEY,
Name NVARCHAR(200) NOT NULL,
Value NVARCHAR(MAX),
Created DATETIME DEFAULT GETDATE()
)
END";
// Execute SQL
}
}
| Criteria | DDS | Custom Table |
|---|---|---|
| Schema | Automatic | Self-managed |
| Query flexibility | Limited | Full SQL |
| Performance | Moderate | Better |
| Complex relations | No | Yes |
| Ease of use | Easy | More complex |
[EPiServerDataStore])Identity)store.LoadAll<T>())