Data Access has been discontinued. Please refer to this page for more information.

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()