如何使用Dapper连接到ProgressDB数据提供程序?

时间:2015-03-31 17:01:55

标签: c# dapper openedge progress-db

请阅读答案的评论,以便更全面地了解问题是什么

首先,我阅读了很多与此相关的其他SO问题,但仍无法使用基本设置。这是我已经读过的相关问题:

Passing query parameters in Dapper using OleDb

编辑:下面的故障排除有点误导。唯一出错的是使用ProgressDB OpenEdge驱动程序从Github示例中查询语法无效。

该问题的答案以及记录在案的Git示例中给出的示例的问题是没有使用真正的ODBC对象,而是使用OleDbConnection对象。这会导致我尝试使用Dapper的情况出现问题。我的场景的一些背景和限制:

  • 我无法更改数据库技术,我们正在连接到Progress DB。连接到DB的连接字符串:connectionString =“PROVIDER = MSDASQL ; DRIVER = {Progress OpenEdge 10.2A Driver}; HOST = ...; PORT = .. 。; DB = mfgsys; UID = ...; PWD = ...; DIL = READ UNCOMMITTED“注意提供者:MSDASQL
  • 根据MSDN,https://msdn.microsoft.com/en-us/library/a6cd7c08%28v=vs.110%29.aspx - “ OLE DB的.NET Framework数据提供程序不能与ODBC的OLE DB提供程序(MSDASQL)一起使用。使用ADO.NET访问ODBC数据源,使用.NET Framework数据提供程序进行ODBC。
  • 当我尝试将OdbcConnection对象与Dapper一起使用时,我收到以下错误:“ System.Data.Odbc.OdbcException:ERROR [HY000] [DataDirect] [ ODBC Progress OpenEdge Wire Protocol驱动程序] [OPENEDGE] SQL语句中的语法错误“=?,年龄=?”(10713)

我使用与其他SO问题完全相同的查询语法:

var row = _odbcConn.Query("select Id = ?, Age = ?", new DynamicParameters(new{foo = 12, bar = 23}) {RemoveUnused = false}).Single();

我还删除了DynamicParameters对象并尝试使用具有相同结果的动态对象:

var row = _odbcConn.Query("select Id = ?, Age = ?", new{foo = 12, bar = 23}).Single();

有没有办法使用OdbcConnection对象完成这个简单的查询?或者这真的与我们正在使用的特定Progress驱动程序有关,因此排除了使用Dapper?

修改

在下面的请求中包含工作ADO.Net代码,Build.FromReader<EmployeeDataModel>(reader)只是循环读取器并使用硬编码映射列并确认可以正常工作:

public class EmployeeRepository : IEmployeeRepository
{
    private readonly OdbcConnection _sqlConn = new OdbcConnection();

    public EmployeeRepository() : this(ConfigurationManager.ConnectionStrings["TCI_Epicor"].ConnectionString) { }
    public EmployeeRepository(string connString)
    {
        _sqlConn.ConnectionString = connString;
    }

    public EmployeeDataModel GetById(string id)
    {
        try
        {
            _sqlConn.Open();
            using (OdbcCommand command = new OdbcCommand())
            {
                command.Connection = _sqlConn;
                command.CommandType = CommandType.Text;
                command.CommandText = GetEmployeeDataQuery();
                command.Parameters.Add("empID", OdbcType.NVarChar);
                command.Parameters["empID"].Value = id;
                var reader = command.ExecuteReader();
                return Build.FromReader<EmployeeDataModel>(reader);
            }
        }
        catch
        {
            return new EmployeeDataModel();
        }
        finally
        {
            _sqlConn.Close();
        }
    }

    private string GetEmployeeDataQuery()
    {
        var sb = new StringBuilder();
        sb.AppendLine("SELECT EmpID as 'EmployeeID',");
        sb.AppendLine("       FirstName + ' ' + LastName as 'EmployeeName'");
        sb.AppendLine("  FROM MFGSYS.PUB.EmpBasic");
        sb.AppendLine(" WHERE EmpID = ?");
        return sb.ToString();
    }
}

1 个答案:

答案 0 :(得分:3)

如果问题是使用匿名(?)参数,则:

var row = _odbcConn.Query(
    "select Id = ?foo?, Age = ?bar?", new { foo = 12, bar = 23 }
).Single();

Dapper将根据您的原始查询重写它,但会知道将哪个参数放在哪里。

但是,如果问题是ODBC提供程序不支持参数:我对此无能为力:(如果您可以在工作 ADO.NET代码中显示如何执行此操作,我可以告诉你如何通过精致的方式更容易地做到这一点。