将实体框架与 Pomelo 一起使用时 MySqlParameter 类型冲突

And*_*iss 2 c# mysql asp.net entity-framework asp.net-core

我有一个Pomelo.EntityFrameworkCore.MySql安装了包的 DAL.EntityFramework 项目。我还有一个安装了 MySql.Data 包的 DAL.MySQL 包。第二个项目用于与 EntityFramework 无关的一般 MySQL 内容。

在 DAL.EntityFramework 中,我有一个使用 ADO.NET 的方法,以便我可以INSERT ... ON DUPLICATE KEY UPDATE对我的数据库执行操作(否则无法使用)。

public async Task<int> SmartUpsert(UserDetails user)
{
    var dbQuery = this.queryProvider.SmartUpsert(user);

    using (var command = this.Context.Database.GetDbConnection().CreateCommand())
    {
        command.CommandText = dbQuery.Query;
        command.CommandType = System.Data.CommandType.Text;
        command.Parameters.AddRange(dbQuery.Params.ToArray());

        this.Context.Database.OpenConnection();
        command.ExecuteNonQuery();
        this.Context.Database.CloseConnection();

        return Convert.ToInt32(command.Parameters["@Output"].Value.ToString());
    }
}
Run Code Online (Sandbox Code Playgroud)

queryProvider注入到类中,实现在 TAP.MySQL 中。这用于提供所需的特定于提供程序的 SQL,而无需将 EF 项目键入特定的 SQL 提供程序。它还创建参数集合(因为这些也是特定于提供程序的)。

public DbQuery SmartUpsert(UserDetails user)
{
    var query = new DbQuery
    {
        Query = "SmartUpsertUserDetails"
    };

    var sqlParams = new List<MySqlParameter>()
    {
        new MySqlParameter("@id", user.UserId),
        new MySqlParameter("@title", user.Title),
        new MySqlParameter("@name", user.Name),
        new MySqlParameter("@surname", user.Surname),
        new MySqlParameter("@email", user.Email)
    };

    var outputParam = new MySqlParameter();
    outputParam.ParameterName = "@result";
    outputParam.MySqlDbType = MySqlDbType.Int32;
    outputParam.Direction = ParameterDirection.Output;
    sqlParams.Add(outputParam);

    query.Params = sqlParams;

    return query;
}
Run Code Online (Sandbox Code Playgroud)

运行此代码时,它command.Parameters.AddRange(dbQuery.Params.ToArray());在行上失败,但出现以下异常:

[A]MySql.Data.MySqlClient.MySqlParameter 不能转换为 [B]MySql.Data.MySqlClient.MySqlParameter。类型 A 源自“C:\Users\Andy.nuget\packages\mysql.data\8.0.13”上下文“Default”中的“MySql.Data, Version=8.0.13.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d” \lib\netcoreapp2.0\MySql.Data.dll'。类型 B 源自“MySqlConnector, Version=0.47.1.0, Culture=neutral, PublicKeyToken=d33d3e53aa5f8c92”,位于“C:\Users\Andy.nuget\packages\mysqlconnector\0.47.1\lib\netcoreapp2”上下文“Default”中.1\MySqlConnector.dll'。

似乎它在附带的 MySqlConnector 包中Pomelo.EntityFrameworkCore.MySql的 MySqlParameter 和安装在我的 DAL.MySQL 项目上的 MySql.Data 中的 MySqlParameter之间变得混淆。

在这种情况下我该怎么办?我不完全确定为什么 Pomelo 使用现有 MySql 类的重复项,但无论如何。

pok*_*oke 5

Pomelo使用的是MySqlConnector而不是 Oracle 自己的包。MySqlConnector 项目站点概述了这样做的好处:

为什么在 Oracle 的连接器/NET 上使用 MySqlConnector?

MySqlConnector 是MySQL 协议的洁净室重新实现,不基于Oracle 的 Connector/NET

异步

  • MySqlConnector:完全异步 I/O
  • Oracle 的连接器/NET:异步调用映射到同步 I/O

发展

  • MySqlConnector:GitHub 上的开放和协作开发
  • Oracle 的连接器/NET:封闭式开发路线图。代码可在GitHub 上查看,一些问题已在论坛中解决

执照

所以基本上,MySqlConnector 只是一个更好的选择。我对 Oracle 自己的软件包的经验也是它们发展缓慢,您通常不知道它们在做什么。例如,当 EF Core 2.0 发布时,Oracle 的 EF 提供程序正在缓慢更新,当他们发布它时,它无法正常工作。但是 GitHub 上的源代码还没有更新,所以你甚至无法知道那里发生了什么。Pomelo 和 MySqlConnector 更加开放,通常更易于使用。

根据这个问题,在 MySqlConnector 中重用相同的命名空间是有意选择作为 Oracle 连接器的直接替代品。同时使用两者并不是有意的用例,尽管如果您真的别无选择,也可以这样做

对于您的项目,这意味着您还应该考虑迁移到 MySqlConnector。这样,您就可以轻松解决冲突。


正如MySqlConnector 的作者Bradley Grainger所评论的那样:

MySql.Data API 有几个部分没有实现(MySqlScript 可能是最大的一个,但很少使用);大多数人发现它 100% 兼容他们对 MySql.Data 的使用。在此处检查迁移文档:https : //mysqlconnector.net/tutorials/migrating-from-connector-net/。如果您的代码依赖于各种 MySql.Data 行为,您可能需要更改一些连接字符串设置。

  • @AndyFurniss 我是 MySqlConnector 的作者。MySql.Data API 有几个部分没有实现(`MySqlScript` 可能是最大的一个,但很少使用);大多数人发现它 100% 兼容他们对 MySql.Data 的使用。在此处检查迁移文档:https://mysql-net.github.io/MySqlConnector/tutorials/migrating-from-connector-net/。如果您的代码依赖于各种 MySql.Data 行为,您可能需要更改一些连接字符串设置。 (2认同)