【问题标题】:Handle dependency conflict in .NET Core project.json处理 .NET Core project.json 中的依赖冲突
【发布时间】:2017-02-27 15:53:09
【问题描述】:

我有一个 .NET Core 项目(针对 .NET 4.6),我必须同时使用 EF Core 和 EF 6。由于我也在使用 MySQL,所以我的 project.json 看起来像这样:

{
    ...
    "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": {}
    },
    ...
}

问题是当我尝试像这样使用 MySqlConnection 类时:

var connection = new MySqlConnection(connectionString);

我收到以下错误:

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'

有没有办法让我准确指定我想使用哪个库MySqlConnection,或者有没有其他方法可以解决这个问题?

这些是我的限制:

  • 我需要 EF Core,因为我们使用 ASP.NET Core Identity(以及其他仅使用 EF Core 的 .NET Core 库)
  • 我需要 EF 6,因为我们发现目前没有适用于 MySQL 的 EF Core 实现足以满足我们的所有需求。
  • 由于我们使用的是 MySQL,我需要将 MySql.Data.Entity 用于 EF 6 和 Pomelo.EntityFrameworkCore.MySql 用于 EF Core。我们已经尝试为 EF Core 使用其他库,但它们带有很多错误。我们发现 Pomelo 是最稳定的。

编辑: 我认为原因是Pomelo.EntityFrameworkCore.MySql 引用了MySqlConnector,它具有命名空间/类MySql.Data.MySqlClient.MySqlConnectionMySql.Data.Entity 也是如此。

【问题讨论】:

  • 使用完整的命名空间? var connection = new MySql.Data.MySqlConnection(connectionString);
  • @DavidG 完整的命名空间是MySql.Data.MySqlClient.MySqlConnection,但这不起作用,因为两个包中都存在MySql.Data.MySqlClient
  • 您可以通过将代码移动到它自己的项目中来解决这个问题,该项目仅引用您需要的单个版本的类。
  • @DavidG 也想过这个问题,但我希望有更好的解决方案,因为使用 EF 6 和 EF Core(模型等)的部分之间共享了大量代码
  • 您可以将模型放入他们自己的项目中并共享。无论如何,我觉得这是一件好事。

标签: mysql entity-framework .net-core entity-framework-core project.json


【解决方案1】:

你可以在你的 project.json 中做类似的事情

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

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

然后在您的代码中,您可以执行如下界面:

#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();
}

然后创建两个继承自IDatabase 接口的对象。一个用于 .NET 4.6.1,另一个用于 .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

最后,在您的应用中,您将在启动时使用上述两个对象之一初始化您的 IDatabase 对象,然后做任何您想做的事情。

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

    database.Initialize();
}

希望对你有帮助

【讨论】:

    猜你喜欢
    • 2015-06-22
    • 2012-08-24
    • 2023-01-26
    • 2016-08-21
    • 1970-01-01
    • 2023-04-07
    • 2015-04-12
    • 2020-01-28
    • 1970-01-01
    相关资源
    最近更新 更多