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

How to: Use Multiple Models With Separate MetadataContainer Instances And The Same Connection String

This article will demonstrate to you the ways to control the aggregation of the metadata for multiple models that use the same connection string. With them you can also resolve the metadata conflict that occurs when multiple models are not in the same namespace. Telerik Data Access will notify you about this with the help of MetadataException with text:

Failed to obtain a Database object. There is already opened context with the same ConnectionName/ConnectionString and its metadata is not compatible with the current one. See the inner exception for more details.

It can be resolved through providing a custom cache key that will uniquely differentiate the two models disregarding the fact that they both use one and the same connection string. The cache key can be provided in one of the following ways:

The number and the type of the models in the data access layer of the application may vary according to your needs.

Override The Init() Method Of The Context

With this approach, you will override the Init() method of the OpenAccessContextBase class directly providing a value for the cache key(Sample 1: Override The Init() Method Of The Context).

Sample 1: Override The Init() Method Of The Context

using Telerik.OpenAccess;
namespace MultipleModels
{
    public partial class FluentModel
    {
        protected override void Init(string connectionString, string cacheKey, 
                  BackendConfiguration backendConfiguration,
                  Telerik.OpenAccess.Metadata.MetadataContainer metadataContainer,
                  System.Reflection.Assembly callingAssembly)
        {
            cacheKey = "my cache key";
            base.Init(connectionString, cacheKey, backendConfiguration, 
                      metadataContainer, callingAssembly);
        }
    }
}
Imports Telerik.OpenAccess
Namespace MultipleModels
    Partial Public Class FluentModel
        Protected Overrides Sub Init(ByVal connectionString As String, 
                  ByVal cacheKey As String, 
                  ByVal backendConfiguration As BackendConfiguration, 
                  ByVal metadataContainer As Telerik.OpenAccess.Metadata.MetadataContainer, 
                  ByVal callingAssembly As System.Reflection.Assembly)
        cacheKey = "my cache key"
        MyBase.Init(connectionString, cacheKey, backendConfiguration,
                    metadataContainer, callingAssembly)
        End Sub
    End Class
End Namespace

This code will be executed once when the first instance of the context is created, during the initialization of the metadata.

The implementation process according to the given example would be as follows:

  1. Open the context class file for edit and override the Init() method assigning the cacheKey parameter with a value of your own choice (here you can apply some custom computed logic).
  2. Save the file.

Override The CacheKey Property Of The Context

With this approach, you will override the CacheKey property of the OpenAccessContextBase class directly providing a value for it (Sample 2: Override The CacheKey Property Of The Context).

Sample 2: Override The CacheKey Property Of The Context

using Telerik.OpenAccess;
namespace MultipleModels
{
    public partial class FluentModel
    {
        protected override string CacheKey
        {
            get
            {
                return "my cache key";
            }
        }
    }
}
Imports Telerik.OpenAccess
Namespace MultipleModels
    Partial Public Class FluentModel
        Protected Overrides ReadOnly Property CacheKey() As String
            Get
                Return "my cache key"
            End Get
        End Property
    End Class
End Namespace

This code will be executed once when the first instance of the context is created, during the initialization of the database object.

The implementation process according to the given example would be as follows:

  1. Open the context class file for edit and override the CacheKey property so that it returns a value of your own choice (here you can apply some custom computed logic).
  2. Save the file.

Modify Fluent Context

With this approach, you will add a private field to the fluent context class so that a specific cache key is provided to the OpenAccessContext / OpenAccessContextBase constructors. It is also applicable for cases when you use directly the OpenAccessContext class without defining a new derived one (Sample 3: Passing A Cache Key to The Context Constructors).

Sample 3: Passing a Cache Key to The Context Constructors

private static string cacheKey = "my cache key";
public FluentModel()
    :base(connectionStringName, cacheKey, backend, metadataSource)
{ }
Private Shared cacheKey As String = "my cache key"
Public Sub New()
    MyBase.New(connectionStringName, cacheKey, backend, metadataSource)
End Sub

The implementation process according to the given example would be as follows:

  1. Open the FluentModel.cs (FluentModel.vb) file.
  2. Add a new private static string field to the FluentModel class called cacheKey and assign it with a value of your own choice (Sample 4: The cacheKey Field):

    Sample 4: The cacheKey Field

    private static string cacheKey = "my cache key";
    
    Private Shared cacheKey As String = "my cache key"
    
  3. Modify the default FluentModel constructor the way that it takes an additional parameter (Sample 5: Modify FluentModel Constructor).

    Sample 5: Modify FluentModel Constructor

    public FluentModel()
            :base(connectionStringName, cacheKey, backend, metadataSource)
        { }
    
    Public Sub New()
            MyBase.New(connectionStringName, cacheKey, backend, metadataSource)
        End Sub
    
  4. Save the file.