将 Dapper 与 SQL Server 一起使用
Posted
技术标签:
【中文标题】将 Dapper 与 SQL Server 一起使用【英文标题】:Using Dapper with 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<object>
,等等。由于这种语法,它们会产生错误:
var output = connection.Query<TheNameOfTheModelToMap>(SPROCName, parms, commandType: CommandType.StoredProcedure).ToList();
我想遵守 DRY 的原则,只编写一种方法来接受任何模型指定、任何存储过程指定并让 Dapper 映射查询结果。有什么可能吗?
【问题讨论】:
实现像public List<T> ExecuteSQLSPROC<T>(string SPROCName, SqlParameter[] parameters)
这样的泛型方法怎么样?
这里的SqlCommand
有什么意义,你似乎没有使用它,而且 Dapper 肯定会为你解决这个问题
另外,您可能应该直接使用 SqlParameter 对象,而不是将它们添加到 DynamicParameters() 集合中。您丢失了参数方向,这将阻止您使用 Out 或 ReturnValue 参数。
你想要public List<TheNameOfTheModelToMap> ExecuteSQLSPROC(string SPROCName, SqlParameter[] parameters, object TheNameOfTheModelToMap)
?从您的签名中不清楚TheNameOfTheModelToMap
参数的类型是什么。
【参考方案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<CarDetail> ExecuteSQLSPROC(SqlParameter[] parameters) => ExecuteSQLSPROC<CarDetail>("ReturnCarDetails", parameters);
即返回 List以上是关于将 Dapper 与 SQL Server 一起使用的主要内容,如果未能解决你的问题,请参考以下文章
如何使 SQL Server 2012 与 php 一起工作?
如何使此 Access sql 语句与 Sql Server 一起使用?
将 IAsyncEnumerable 与 Dapper 一起使用