Updating the Context Metadata
This article is relevant to entity models that utilize the deprecated Visual Studio integration of Telerik Data Access. The current documentation of the Data Access framework is available here.
Telerik Data Access caches the metadata after the first OpenAccessContext is created. Whenever the metadata needs to be changed, a complete new configuration has to be instantiated, replacing the old one. However, this could be a performance overhead.
There is a smarter way to load modules in Telerik Data Access, i.e. it is possible to dynamically build the metadata, during the application execution without blocking the application part using the older metadata definitions. The OpenAccessContext class now provides a static method named ReplaceMetadata which replaces the cached metadata container without disposing of the Database object, which contains the cached metadata. The method will use the context passed in to detect the underlying instances and replace the metadata definition for all NEW context instances. The existing instances are still using the old metadata to finish their work. The old metadata configuration stays alive until the last old context is disposed.
After metadata replacement the following caches are fully cleared and allow adding only new objects, based on the new metadata:
- L2 Cache
- L2 Query Cache
- Prepared Statement Cache
The following example demonstrates this functionality when used to merge multiple rlinq files at runtime. The first model contains only the Category class from the Northwind database and the second model contains only the Product class. After merging the two containers and replacing the metadata, the Product objects are accessible from the context of Model1.
Model1 context1 = new Model1();
var categories = context1.Categories.ToList();
MetadataContainer model1 = XmlMetadataSource
.FromAssemblyResource("EntityDiagrams1.rlinq").GetModel();
model1.Name = null;
MetadataContainer model2 = XmlMetadataSource
.FromAssemblyResource("EntityDiagrams2.rlinq").GetModel();
model2.Name = null;
AggregateMetadataSource newSource = new AggregateMetadataSource(model1, model2);
OpenAccessContextBase.ReplaceMetadata(context1, newSource.GetModel(), Callback);
context1 = new Model1();
var products = context1.GetAll<Product>().ToList();
Dim context1 As New Model1()
Dim categories = context1.Categories.ToList()
Dim model1 As MetadataContainer = XmlMetadataSource _
.FromAssemblyResource("EntityDiagrams1.rlinq").GetModel()
model1.Name = Nothing
Dim model2 As MetadataContainer = XmlMetadataSource _
.FromAssemblyResource("EntityDiagrams2.rlinq").GetModel()
model2.Name = Nothing
Dim newSource As New AggregateMetadataSource(model1, model2)
OpenAccessContextBase.ReplaceMetadata(context1, newSource.GetModel(), Callback)
context1 = New Model1()
Dim products = context1.GetAll(Of Product)().ToList()
If you want to perform additional work like schema migration, you could pass a callback to the ReplaceMetadata method (this is the third parameter).
public static void Callback(object sender, SchemaUpdateArgs args)
{
SchemaUpdateInfo schemaUpdateInfo = args.SchemaHandler
.CreateUpdateInfo(new SchemaUpdateProperties());
string ddl = schemaUpdateInfo.Script;
}
Public Shared Sub Callback(ByVal sender As Object, ByVal args As SchemaUpdateArgs)
Dim _schemaUpdateInfo As SchemaUpdateInfo = args.SchemaHandler _
.CreateUpdateInfo(New SchemaUpdateProperties())
Dim ddl As String = _schemaUpdateInfo.Script
End Sub