0

I have a .NET Core project (targeting .NET 4.6) where I have to use both EF Core and EF 6. Since I'm also using MySQL, my project.json looks something like this:

{
    ...
    "dependencies": {
        "EntityFramework": "6.1.3", // For EF 6
        "MySql.Data.Entity": "6.9.9", // For EF 6 and MySQL
        "Pomelo.EntityFrameworkCore.MySql": "1.1.0", // For EF Core
        ...
    },
    "frameworks": {
        "net461": {}
    },
    ...
}

The problem is when I try to use the class MySqlConnection like this:

var connection = new MySqlConnection(connectionString);

I get the following error:

The type 'MySqlConnection' exists in both 
'MySql.Data, Version=6.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d' and
'MySqlConnector, Version=0.7.2.0, Culture=neutral, PublicKeyToken=null'

Is there a way for me to specify exactly from which library I want to use MySqlConnection, or is there any other way to solve this?

These are my constraints:

  • I need EF Core since we use ASP.NET Core Identity (and other .NET Core libraries using only EF Core)
  • I need EF 6 since we found that at the moment there are no EF Core implementations for MySQL that are good enough for all our needs.
  • Since we are using MySQL, I need to use MySql.Data.Entity for EF 6 and Pomelo.EntityFrameworkCore.MySql for EF Core. We've tried to use other libraries for EF Core, but they come with a lot of bugs. We found Pomelo to be the most stable.

EDIT: I think the reason is that Pomelo.EntityFrameworkCore.MySql references MySqlConnector which has the namespace/class MySql.Data.MySqlClient.MySqlConnection, and so does MySql.Data.Entity.

Joel
  • 8,502
  • 11
  • 66
  • 115
  • Use the full namespace? `var connection = new MySql.Data.MySqlConnection(connectionString);` – DavidG Feb 27 '17 at 15:54
  • @DavidG The full namespace is `MySql.Data.MySqlClient.MySqlConnection` but that doesn't work since `MySql.Data.MySqlClient` exists in both packages. – Joel Feb 27 '17 at 15:59
  • You might be able to get around this by moving the code into it's own project that only references a single version of the class you need. – DavidG Feb 27 '17 at 16:02
  • @DavidG Thought about that too, but I'm hoping that there is a better solution, since there is quite a lot of code shared between the parts using EF 6 and EF Core (models, etc) – Joel Feb 27 '17 at 16:16
  • You can put the models in their own project and share that too. I find that is a good thing to do anyway. – DavidG Feb 27 '17 at 16:22
  • @DavidG Yeah I know. But I'm actually trying to minimize the number of projects for the solution, so I'm hoping there is another fix. – Joel Feb 27 '17 at 16:24
  • I'd be curious why reducing the number of projects is important, it's just another abstraction to separate your concerns. – DavidG Feb 27 '17 at 16:25
  • @DavidG As solutions grow and the number of projects in the solution increases, VS load time and build times are increasing. I find that keeping projects to a minimum decreases time spent on waiting for my computer to do things :) – Joel Feb 28 '17 at 07:03

1 Answers1

0

You can do something like that in your project.json

"frameworks": {
    "netstandard1.6": {
      "imports": "dnxcore50",
      "dependencies": {
        // Your .NET Core dependencies
      }
    },

    "net461": {
      "dependencies": {
           // Your .NET 4.6.1 dependencies
      }
    }
  }

Then in your code you can do an interface like:

#if NET461
// put your EF usings for .NET 4.6.1 here
#else
// put your EFCore usings for .NET Core
#endif

public interface IDatabase
{
    void Initialize();
    DbContext GetContext();
}

Then create two objects that inherits from IDatabase interface. One for .NET 4.6.1 and the other for .NET Core

.NET 4.6.1

#if NET461
// put your usings for EF for net461

public class Database461 : IDatabase
{
    private DbContext context;

    public Database461(DbContext context)
    {
        // ...
    }

    public void Initialize()
    {
        // initialize stuff if you want
    }

    public DbContext GetContext()
    {
        return this.context;
    }
}

#endif

.NET Core*

// notice here that i've put a "!" that means "not"
#if !NET461
// put your usings for EF Core

public class DatabaseNetCore : IDatabase
{
    private DbContext context;

    public DatabaseNetCore (DbContext context)
    {
        // ...
    }

    public void Initialize()
    {
        // initialize stuff if you want
    }

    public DbContext GetContext()
    {
        return this.context;
    }
}

#endif

Finally, in your app, you will initialize at startup your IDatabase object using one of the two objects above and do whatever you want.

// At startup, somewhere in your app...
static IDatabase database;
public InitializeDatabase()
{
#if !NET461
    database = new DatabaseNetCore(...);
#else
    database = new Database461(...);
#endif

    database.Initialize();
}

Hope it helps

Eastrall
  • 7,609
  • 1
  • 16
  • 30