【问题标题】:Using Dapper with SQL Server将 Dapper 与 SQL Server 一起使用
【发布时间】:2021-03-04 21:27:16
【问题描述】:

我目前正在使用 C# (Visual Studio 2019) 和使用 Dapper 的 SQL Server 2017 开发应用程序。下面是一个现在可以很好地在 SQL Server 中执行存储过程的例程。

C#代码使用MVVM框架,我目前有60个模型类来映射SQL Server数据库中的表。大约有 120 个存储过程产生结果,这些结果使用 Dapper 映射到模型类。

将以下代码 sn-p 视为伪代码(但它实际上可以执行存储过程并返回正确的结果)。

public List<SomeDefinedModel> ExecuteSQLSPROC(string SPROCName, SqlParameter[] parameters)
{
    using (IDbConnection connection = new System.Data.SqlClient.SqlConnection(DBHelper.CNNVal("MYLocalServer")))
    {
        System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand();
        command.Connection = (SqlConnection)connection;
        command.CommandText = SPROCName;

        DynamicParameters parms = new DynamicParameters();

        for (int i = 0; i < parameters.Length; i++)
        {
            var parmname = parameters[i].ParameterName;
            var parmvalue = parameters[i].Value;
            parms.Add(parmname, parmvalue);
        }

        var output = connection.Query<SomeDefinedModel>(SPROCName, parms, commandType: CommandType.StoredProcedure).ToList();

        return output;
    }
}

我想改变这个例程所以这个例程使它的方法签名如下:

public List<TheNameOfTheModelToMap> ExecuteSQLSPROC(string SPROCName, SqlParameter[] parameters, TheNameOfTheModelToMap)

也就是说,Dapper 要映射到的模型的名称是一个变量——它可以是任何有效的模型。我已将变量TheNameOfTheModelToMap 定义为类型对象,并将返回值定义为var、List&lt;object&gt;,等等。由于这种语法,它们会产生错误:

var output = connection.Query<TheNameOfTheModelToMap>(SPROCName, parms, commandType: CommandType.StoredProcedure).ToList();

我想遵守 DRY 的原则,只编写一种方法来接受任何模型指定、任何存储过程指定并让 Dapper 映射查询结果。有什么可能吗?

【问题讨论】:

  • 实现像public List&lt;T&gt; ExecuteSQLSPROC&lt;T&gt;(string SPROCName, SqlParameter[] parameters)这样的泛型方法怎么样?
  • 这里的SqlCommand 有什么意义,你似乎没有使用它,而且 Dapper 肯定会为你解决这个问题
  • 另外,您可能应该直接使用 SqlParameter 对象,而不是将它们添加到 DynamicParameters() 集合中。您丢失了参数方向,这将阻止您使用 Out 或 ReturnValue 参数。
  • 你想要public List&lt;TheNameOfTheModelToMap&gt; ExecuteSQLSPROC(string SPROCName, SqlParameter[] parameters, object TheNameOfTheModelToMap)?从您的签名中不清楚TheNameOfTheModelToMap 参数的类型是什么。

标签: c# sql-server dapper


【解决方案1】:

我认为你只需要一个像这样的通用方法:


public List<T> ExecuteSQLSPROC<T>(string SPROCName, SqlParameter[] parameters)
{
    using (var connection = new System.Data.SqlClient.SqlConnection(DBHelper.CNNVal("MYLocalServer")))
    {
        var parms = new DynamicParameters();
        foreach (var parameter in parameters)
            parms.Add(parameter.ParameterName, parameter.Value);

        var output = connection.Query<T>(
                SPROCName,
                parms,
                commandType: CommandType.StoredProcedure
            )
            .ToList();

        return output;
    }
}


所有其他方法都成为它的专门调用:

public List<SomeDefinedModel> ExecuteOneProc(SqlParameter[] parameters)
  => ExecuteSQLSPROC<SomeDefinedModel>("OneProcName", parameters);

这适合您的用例吗? 如果您需要一个处理单个值的过程(不会使用 Dapper 的 Query 方法),您只需创建 ExecuteSQLSPROC 的特殊变体,例如 ExecuteStoredProcSingleRow 或类似的东西。

【讨论】:

  • 我使用以下语法来调用新版本的 ExecuteSQLSPROC。 ExecuteSQLSPROC 方法按照建议正确编译,但调用新方法的代码如下: public List ExecuteSQLSPROC(SqlParameter[] parameters) => ExecuteSQLSPROC("ReturnCarDetails", parameters);将无法编译并产生以下错误: CS0106 修饰符 'public'‌ 对此项无效指 lambda 表达式之后的所有内容)
  • 好吧,在我的示例中,您必须指定存储过程返回的类型。类似于:List&lt;CarDetail&gt; ExecuteSQLSPROC(SqlParameter[] parameters) =&gt; ExecuteSQLSPROC&lt;CarDetail&gt;("ReturnCarDetails", parameters); 即返回 List 而不是 List,并调用指定泛型类型参数的泛型方法。
猜你喜欢
  • 2012-03-26
  • 2020-05-14
  • 1970-01-01
  • 1970-01-01
  • 2019-11-15
  • 1970-01-01
  • 2014-06-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多