How to: Merge FluentMetadataSources
The AggregateMetadataSource can be used to combine other MetadataSource instances and produce a new MetadataContainer that contains the combined metadata. The purpose of this tutorial is to show you how to work with AggregateMetadataSource.
It is not possible to use the AggregateMetadataSource class for merging data from different database.
For this walkthrough, the following projects and classes will be used. In order to use the AggregateMetadataSource, you will need to add references to Telerik.OpenAccess.dll and Telerik.OpenAccess.35.Extensions.dll in your projects.
Project AssemblyA - it contains the following classes:
-
Person - the Person object has a reference to Address, which is defined in the AssemblyB.
using AssemblyB; namespace AssemblyA { public class Person { public string Name { get; set; } public int Id { get; set; } public Address Address { get; set; } } }
Imports AssemblyB Public Class Person Public Property Name() As String Public Property Id() As Integer Public Property Address() As Address End Class
-
FluentMetadataSourceA - a custom FluentMedataSource class that provides a mapping configuration for the Person class.
using System.Collections.Generic; using Telerik.OpenAccess.Metadata.Fluent; namespace AssemblyA { public class FluentMetadataSourceA : FluentMetadataSource { protected override IList<MappingConfiguration> PrepareMapping() { IList<MappingConfiguration> preparedConfigurations = new List<MappingConfiguration>(); MappingConfiguration<Person> personConfiguration = new MappingConfiguration<Person>(); personConfiguration.MapType().ToTable("People"); preparedConfigurations.Add(personConfiguration); return preparedConfigurations; } } }
Imports Telerik.OpenAccess.Metadata.Fluent Public Class FluentMetadataSourceA Inherits FluentMetadataSource Protected Overrides Function PrepareMapping() As IList(Of MappingConfiguration) Dim preparedConfigurations As IList(Of MappingConfiguration) = New List(Of MappingConfiguration)() Dim personConfiguration As New MappingConfiguration(Of Person)() personConfiguration.MapType().ToTable("People") preparedConfigurations.Add(personConfiguration) Return preparedConfigurations End Function End Class
Project AssemblyB - it contains the following classes:
-
Address
namespace AssemblyB { public class Address { public string Country { get; set; } public string Street { get; set; } } }
Public Class Address Public Property Country() As String Public Property Street() As String End Class
-
FluentMetadataSourceB - a custom FluentMedataSource class that provides a mapping configuration for the Address class.
using System.Collections.Generic; using Telerik.OpenAccess.Metadata.Fluent; namespace AssemblyB { public class FluentMetadataSourceB : FluentMetadataSource { protected override IList<MappingConfiguration> PrepareMapping() { IList<MappingConfiguration> preparedConfigurations = new List<MappingConfiguration>(); MappingConfiguration<Address> addressConfiguration = new MappingConfiguration<Address>(); addressConfiguration.MapType().ToTable("Addresses"); preparedConfigurations.Add(addressConfiguration); return preparedConfigurations; } } }
Imports Telerik.OpenAccess.Metadata.Fluent Public Class FluentMetadataSourceB Inherits FluentMetadataSource Protected Overrides Function PrepareMapping() As IList(Of MappingConfiguration) Dim preparedConfigurations As IList(Of MappingConfiguration) = _ New List(Of MappingConfiguration)() Dim addressConfiguration As New MappingConfiguration(Of Address)() addressConfiguration.MapType().ToTable("Addresses") preparedConfigurations.Add(addressConfiguration) Return preparedConfigurations End Function End Class
The AggregateMetadataSource can be used in the following manner:
AggregateMetadataSource aggregateMetadataSource = new AggregateMetadataSource(
new FluentMetadataSourceA(), new FluentMetadataSourceB(), AggregationOptions.Late);
MetadataContainer metadataContainer = aggregateMetadataSource.GetModel();
Dim _aggregateMetadataSource As New AggregateMetadataSource(New FluentMetadataSourceA(), _
New FluentMetadataSourceB(), AggregationOptions.Late)
Dim _metadataContainer As MetadataContainer = _aggregateMetadataSource.GetModel()
The merged metadata container will contain two persistent types - Address and Person.
The AggregateMetadataSource class uses a special algorithm internally to resolve references when merging objects. Suppose you have a class A and a class B, which classes you want to merge. Class A has a reference to class C. In this case, when you merge class A and class B, the AggregateMetadataSource class cannot resolve the reference from A to C out of the box. Reference resolution can be controlled by specifying AggregationOptions in the AggregateMetadataSource. For more information, check out the How to: Control Reference Resolution topic.
You can consume the merged metadata container as demonstrated below:
FluentModel1 context1 = new FluentModel1( "SofiaCarRentalConnection", metadataContainer );
Car cars = context1.GetAll<Car>().FirstOrDefault();
RentalOrder rentalOrder = context1.GetAll<RentalOrder>().FirstOrDefault();
Dim context1 As New FluentModel1("SofiaCarRentalConnection", _metadataContainer)
Dim cars As Car = context1.GetAll(Of Car)().FirstOrDefault()
Dim _rentalOrder As RentalOrder = context1.GetAll(Of RentalOrder)().FirstOrDefault()