在进行数据库操作时,我们经常需要对多个参数进行拼装,尤其是在动态查询语句中,这项工作会更加繁琐和复杂。这时DynamicParameters
就能派上用场了。DynamicParameters
是Dapper中的一个类,它能够帮助我们轻松地构造参数,减少冗余代码的编写,提高代码的可读性。
一、DynamicParameters的节点
DynamicParameters
类位于Dapper命名空间下,我们需要在代码中引入using Dapper;
才能使用它。使用DynamicParameters
,最基本的就是设置参数。我们可以通过以下代码来设置参数:
DynamicParameters parameters = new DynamicParameters();
parameters.Add("userId", 1);
parameters.Add("userName", "admin");
parameters.Add("age", null);
parameters.Add("enable", true);
其中,Add
方法的第一个参数是参数名,第二个参数是参数值。如果是空值,可以将参数值传递为null
,如果是布尔类型,也可以直接传递true
或false
。如果我们需要手动指定一个参数的类型,可以使用Add
方法的第三个参数:
DynamicParameters parameters = new DynamicParameters();
parameters.Add("userId", 1, DbType.Int32);
parameters.Add("userName", "admin", DbType.String);
parameters.Add("age", null, DbType.Int32);
parameters.Add("enable", true, DbType.Boolean);
在这个例子中,我们将userId
参数指定为Int32
类型,userName
参数指定为字符串类型,age
参数指定为Int32
类型,enable
参数指定为Boolean
类型。但对于大多数情况来说,Dapper可以自动识别参数类型,我们不必手动指定。
二、DynamicParameters参数的类型
除了基本的参数类型,DynamicParameters
还支持以下几种类型的参数:
1. 动态参数
动态参数可以用来保存一系列键值对。如果我们想要查询满足一组特定条件的数据,就可以使用动态参数。下面是一个使用动态参数查询的例子:
DynamicParameters parameters = new DynamicParameters();
parameters.AddDynamicParams(new { UserId = 1, UserName = "admin" });
var sql = "SELECT * FROM Users WHERE 1 = 1";
if (parameters != null && parameters.ParameterNames.Count() > 0)
{
foreach (string name in parameters.ParameterNames)
{
sql += " AND " + name + "= @" + name;
}
var users = connection.Query<User>(sql, parameters);
}
在这个例子中,我们首先调用AddDynamicParams
方法,将一个匿名类型对象添加到DynamicParameters
实例中。然后,对于每一个参数名,我们都将其添加到查询语句的WHERE
条件中,并将DynamicParameters
实例传递给Query
方法。最后,就可以得到我们想要的结果。我们可以将这种方式扩展到任何查询语句中,从而实现更为复杂的动态查询。
2. 支持数组参数
在查询中,我们有时需要使用数组参数。比如,我们需要查询某个部门中所有的员工信息,而部门编号是一个整型数组。Dapper支持使用数组参数,具体实现方式如下:
int[] departmentIds = { 1, 2, 3 };
var sql = "SELECT * FROM Employees WHERE DepartmentId IN @DepartmentIds";
var parameter = new DynamicParameters();
parameter.Add("DepartmentIds", departmentIds, DbType.Int32, ParameterDirection.Input);
var result = connection.Query<Employee>(sql, parameter);
在这个例子中,我们首先定义了一个整型数组departmentIds
,然后在查询语句中使用IN
关键字查询DepartmentId
是否在departmentIds
数组中。接着,我们创建了一个DynamicParameters
实例,使用Add
方法将数组参数DepartmentIds
添加到DynamicParameters
中,并指定了参数类型和方向。最后,我们可以将DynamicParameters
实例传递给Query
方法,得到我们想要的结果。
3. 动态参数支持DataTable类型
如果我们需要批量插入或更新数据,使用DataTable
类型的数组会比较方便。Dapper提供了对DataTable
类型的支持,可以将DataTable
作为DynamicParameters
的参数值进行传递。下面是一个使用DataTable
批量插入数据的例子:
public void BulkInsert(DataTable table)
{
using IDbConnection connection = new MySqlConnection(Configuration.GetValue<string>("ConnectionString"));
IDbTransaction transaction = null;
try
{
connection.Open();
transaction = connection.BeginTransaction();
connection.Execute("CREATE TEMPORARY TABLE IF NOT EXISTS TempTable (Id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, Name VARCHAR(50), Age INT)");
connection.Execute("INSERT INTO TempTable (Id, Name, Age) VALUES(0, '', 0)");
connection.Execute("DELETE FROM TempTable WHERE Id=0");
using (var bulkCopy = new MySqlBulkCopy((MySqlConnection)connection, transaction))
{
bulkCopy.BatchSize = 1000;
bulkCopy.DestinationTableName = "TempTable";
foreach (DataColumn column in table.Columns)
{
bulkCopy.ColumnMappings.Add(column.ColumnName, column.ColumnName);
}
bulkCopy.WriteToServer(table);
}
connection.Execute("INSERT INTO Users (Name, Age) SELECT Name, Age FROM TempTable");
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
throw ex;
}
}
在这个例子中,我们首先定义了一个BulkInsert
方法,它接受一个DataTable
类型的参数table
。接着,我们使用MySqlBulkCopy
进行批量插入操作。首先,我们创建了一个临时表TempTable
,并在其中插入一条空记录,然后删除该记录。接着,我们使用MySqlBulkCopy
的ColumnMappings
属性指定每个列名称的映射关系,并将table
对象写入到数据库中。最后,我们在Users
表中插入由TempTable
生成的数据。如果出现异常,则回滚事务。
三、总结
DynamicParameters
类可以帮助我们轻松地构造参数,减少冗余代码的编写,提高代码的可读性。除了基本的参数类型,DynamicParameters
还支持动态参数、数组参数和DataTable
类型的参数。它使我们能够更方便地使用Dapper进行数据库操作,并且可以帮助我们完成更为复杂和高效的操作。