6

This is my first question, and I know I should search before asking anything, I am sure that I have done search but I didn't find appropriate information.

I am using code-first approach to implement my Context and my Models, So I have a simple Context like:

[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
public partial class MultipleContext : DbContext
{
    public MariaDBContext(string connection) : base(connection)
    {
        //Database.SetInitializer<MultipleDBContext>(new MariaDbInitializer());
    }
    public virtual DbSet<Test> Tests { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Test>().ToTable("test")
            .HasKey(e => e.ID);
    }
}

and my model:

public partial class Test
{
    public int ID { get; set; }

    public string Name { get; set; }

    public string Family { get; set; }
}

and I have two connectionstrings like below:

<connectionStrings> 
    <add name="MariaDBContext" connectionString="server=127.0.0.1;user id=root;password=xx;database=sb1" providerName="MySql.Data.MySqlClient" />
    <add name="SqlDBContext" connectionString="Data Source=localhost;Integrated Security=SSPI;Initial Catalog=db1" providerName="System.Data.SqlClient" />
  </connectionStrings>

and my EF config :

<entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
            <parameters>
                <parameter value="mssqllocaldb" />
            </parameters>
        </defaultConnectionFactory>
        <providers>
            <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
        </providers>
    </entityFramework>

I want to write to different Db just by changing ConnectionString like:

MultipleDBContext context = new MultipleDBContext(System.Configuration.ConfigurationManager.ConnectionStrings["MariaDBContext"].ToString());
var xx = context.Tests.Where(x => x.ID > 0).ToList();
context.Tests.Add(new Test()
{
    Name = "name",
    Family = ""
});
context.SaveChanges();
xx = context.Tests.Where(x => x.ID > 0).ToList();
//Use sql connection

MultipleDBContext sqlContext = new MultipleDBContext (System.Configuration.ConfigurationManager.ConnectionStrings["SqlDBContext"].ToString());
var sqlTest = sqlContext.Tests.Where(x => x.ID > 0).ToList();
sqlContext.Tests.Add(new Test()
{
    Name = "name_" + DateTime.Now.Ticks.ToString(),
    Family = "family_" + DateTime.Now.Ticks.ToString(),
});
sqlContext.SaveChanges();
sqlTest = sqlContext.Tests.Where(x => x.ID > 0).ToList();

the first context works fine but the sqlcontext get the below exception:

An unhandled exception of type 'System.NullReferenceException' occurred in EntityFramework.dll Additional information: Object reference not set to an instance of an object

but if I remove the DbConfigurationType decoration then the second sqlContext works fine the first one give below exception:

An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in EntityFramework.dll Additional information: Login failed for user 'root'.

I know that is because of DbConfigurationType which can define in application start or decorate on Context or defined in config file....

but how can I have this (multiple connectionstrings and one context)?

  • 1
    It is because of different provider. – Aria Jun 11 '18 at 09:31
  • 1
    Pretty sure EF works on the premise of [1context = 1database] at a time. – Wurd Jun 11 '18 at 09:32
  • @Wurd, So you say there is no way to implement above scenario ? –  Jun 11 '18 at 09:36
  • 1
    Is one context for MySql db and the other context for SQL Server? Also why is the type of one context `SqlDBContext` and the other one `MariaDBContext` but you only provided implementation for `MariaDBContext `? There is no issue for the different instance but same type context to operate on multiple databases, provided that the schema will match your entities. – Vidmantas Blazevicius Jun 11 '18 at 09:40
  • @VidmantasBlazevicius, I have missed it, I just edited, I used `MultipleDbContext` for different `ConnectionString` –  Jun 11 '18 at 09:44
  • Looking at your connection strings - one of the connection strings is for `providerName="System.Data.SqlClient"` provider whereas your EF config only configured for ` – Vidmantas Blazevicius Jun 11 '18 at 09:46
  • I just remember having an argument with someone that switching connection strings could be done but I was proved wrong. – Wurd Jun 11 '18 at 10:05

1 Answers1

2

I am pretty sure this is because of configuration in config file (multiple provider),

As far as I know you should change provider at run time for related database..

So as your configuration file seems configed for MySql provider :

 <providers>
    <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
 </providers>

so you must define provider per connectionstring like below(just for sample):

<providers>
  <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
  <provider invariantName="Oracle.ManagedDataAccess.Client" type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
  <provider invariantName="Npgsql" type="Npgsql.NpgsqlServices, EntityFramework6.Npgsql" />
</providers>

but by the above config the problem won't gone because there are some anothers tips and tricks to do this such as different schema in different database,different attributes like [DbColumn(msSqlName: "Id", oracleName: "ID", postgreSqlName: "id")] and etc....

So as I experience this is better to have separate context per database but at the end there are some helpful links which will help you to resolve the problem.

the first is Entity Framework Multi DB Support and This

apart from anything you should know is this good idea to have multiple db per single context or not, this issue discussed before here.

Hope this answer help you.

Aria
  • 3,724
  • 1
  • 20
  • 51