Dapper 多插入返回插入的对象
Dapper multi insert returning inserted objects
使用 Dapper 我想实现一个采用 IEnumberable
类型 User
对象的方法。现在,User
看起来如下:
public class User
{
public int UserId { get; internal set; }
public DateTime DateCreated { get; internal set; }
public DateTime DateChanged { get; internal set; }
public string Username { get; set; }
}
这里的重点是 UserId
、DateCreated
和 DateChanged
永远不能通过对象设置,因此 internal
关键字。相反,数据库将填充这些值。
因为对象因此被修改为插入操作的一部分,所以我想 return 另一个 IEnumerable
类型 User
的对象,但这次填充了相应的属性。
最近我意识到我可以让 Dapper 循环遍历 IEnumerable
中的 User
个对象,如下所示:
public int Insert(IEnumerable<User> users)
{
string sql = string.Format("INSERT INTO [User] (Username) VALUES (@Username)");
return GetOpenConnection().Execute<User>(sql, users);
}
这很好,因为我不必自己编写 foreach
。现在,这里的问题是 Execute
只会 return 实际插入的行数。
所以我尝试使用 Query
如下:
public IEnumerable<User> Insert(IEnumerable<User> users)
{
string sql = string.Format("INSERT INTO [User] (Username) VALUES (@Username) SELECT * FROM [User] WHERE UserId = scope_identity()");
return GetOpenConnection().Query<User>(sql, users);
}
然而,这只是抛出一个 InvalidOperationException
异常消息 "An enumerable sequence of parameters (arrays, lists, etc) is not allowed in this context"。
我坚持这个。我怎样才能使这项工作?
我是否必须循环我的输入 IEnumerable
对循环体内的每个对象执行 Query
?这样,如果我想在同一事务中插入所有 User
对象,Query
方法的 IDbTransaction
参数将无用,因此我必须将整个循环包装在事务中将交易传递给 Query
.
使用 Dapper 插入多个对象的 "proper" 方法是什么,return 将完全填充的对象返回给调用者?
要使用 Dapper.Net 插入或更新对象列表,您不能使用查询
connection.Query<Object>("your_query",your_list)
//connection.Query<Object>: use to select IEnumrable<object> from db
//connection.QueryMultiple: use to execut multiple query at once then read result one by one
var sql =
@"
select * from Customers where CustomerId = @id
select * from Orders where CustomerId = @id
select * from Returns where CustomerId = @id";
using (var multi = connection.QueryMultiple(sql, new {id=selectedId}))
{
var customer = multi.Read<Customer>().Single();
var orders = multi.Read<Order>().ToList();
var returns = multi.Read<Return>().ToList();
...
}
你应该只使用 Execute 进行多插入或更新
Execute("your_query",your_list, your_transaction);
因此,如果您需要多次插入和 return 插入记录的 ID
// **using transaction depend on your needs**
//多插入和return全记录示例
string query = @"Insert Into _TableName ( _columns)
OUTPUT INSERTED.*
values ( _parameters )"; //parameters should be same as object properties name to let dapper do correct mapping
[OUTPUT INSERTED.*] 将 return 完整插入带有 id 的行,您可以通过替换自由 return 任何 属性带有 属性name [OUTPUT INSERTED.Id] 的星号将 return 只有 id
// 适合小列表
for (int i = 0; i < youList.Count-1; i++)
{
youList[i] = DbConnection.Query<object>(query, youList[i]).FirstOrDefault();
} // for loop is better for preformance
//对于大列表,您可以使用 SqlBulkCopy 查看此 link here
对于 MySql 和 .Net Core 2.2,您可以这样做:
public async Task<IEnumerable<T>> AddandReturn<T> (object dp, string SPName) {
using (MySqlConnection con = new MySqlConnection (connString)) {
using (MySqlCommand cmd = new MySqlCommand (SPName, con)) {
IEnumerable<T> resultList = await con.QueryAsync<T> (SPName, dp, commandType : CommandType.StoredProcedure);
return resultList;
}
}
}
并从 mysql 获取 ID 或对象,您的存储过程应如下所示:
declare id int default 0;
insert into objectTable(fields...)
values (fieldvalue...);
set id=last_insert_id();
select * from objectTable where objectTableid=id;
** 请注意Mysql 存储过程参数名称应与 .Net Core 中的对象属性匹配。
希望这对使用 MySql 存储过程和 .Net Core
的人有所帮助
使用 Dapper 我想实现一个采用 IEnumberable
类型 User
对象的方法。现在,User
看起来如下:
public class User
{
public int UserId { get; internal set; }
public DateTime DateCreated { get; internal set; }
public DateTime DateChanged { get; internal set; }
public string Username { get; set; }
}
这里的重点是 UserId
、DateCreated
和 DateChanged
永远不能通过对象设置,因此 internal
关键字。相反,数据库将填充这些值。
因为对象因此被修改为插入操作的一部分,所以我想 return 另一个 IEnumerable
类型 User
的对象,但这次填充了相应的属性。
最近我意识到我可以让 Dapper 循环遍历 IEnumerable
中的 User
个对象,如下所示:
public int Insert(IEnumerable<User> users)
{
string sql = string.Format("INSERT INTO [User] (Username) VALUES (@Username)");
return GetOpenConnection().Execute<User>(sql, users);
}
这很好,因为我不必自己编写 foreach
。现在,这里的问题是 Execute
只会 return 实际插入的行数。
所以我尝试使用 Query
如下:
public IEnumerable<User> Insert(IEnumerable<User> users)
{
string sql = string.Format("INSERT INTO [User] (Username) VALUES (@Username) SELECT * FROM [User] WHERE UserId = scope_identity()");
return GetOpenConnection().Query<User>(sql, users);
}
然而,这只是抛出一个 InvalidOperationException
异常消息 "An enumerable sequence of parameters (arrays, lists, etc) is not allowed in this context"。
我坚持这个。我怎样才能使这项工作?
我是否必须循环我的输入 IEnumerable
对循环体内的每个对象执行 Query
?这样,如果我想在同一事务中插入所有 User
对象,Query
方法的 IDbTransaction
参数将无用,因此我必须将整个循环包装在事务中将交易传递给 Query
.
使用 Dapper 插入多个对象的 "proper" 方法是什么,return 将完全填充的对象返回给调用者?
要使用 Dapper.Net 插入或更新对象列表,您不能使用查询
connection.Query<Object>("your_query",your_list)
//connection.Query<Object>: use to select IEnumrable<object> from db
//connection.QueryMultiple: use to execut multiple query at once then read result one by one
var sql =
@"
select * from Customers where CustomerId = @id
select * from Orders where CustomerId = @id
select * from Returns where CustomerId = @id";
using (var multi = connection.QueryMultiple(sql, new {id=selectedId}))
{
var customer = multi.Read<Customer>().Single();
var orders = multi.Read<Order>().ToList();
var returns = multi.Read<Return>().ToList();
...
}
你应该只使用 Execute 进行多插入或更新
Execute("your_query",your_list, your_transaction);
因此,如果您需要多次插入和 return 插入记录的 ID
// **using transaction depend on your needs**
//多插入和return全记录示例
string query = @"Insert Into _TableName ( _columns)
OUTPUT INSERTED.*
values ( _parameters )"; //parameters should be same as object properties name to let dapper do correct mapping
[OUTPUT INSERTED.*] 将 return 完整插入带有 id 的行,您可以通过替换自由 return 任何 属性带有 属性name [OUTPUT INSERTED.Id] 的星号将 return 只有 id
// 适合小列表
for (int i = 0; i < youList.Count-1; i++)
{
youList[i] = DbConnection.Query<object>(query, youList[i]).FirstOrDefault();
} // for loop is better for preformance
//对于大列表,您可以使用 SqlBulkCopy 查看此 link here
对于 MySql 和 .Net Core 2.2,您可以这样做:
public async Task<IEnumerable<T>> AddandReturn<T> (object dp, string SPName) {
using (MySqlConnection con = new MySqlConnection (connString)) {
using (MySqlCommand cmd = new MySqlCommand (SPName, con)) {
IEnumerable<T> resultList = await con.QueryAsync<T> (SPName, dp, commandType : CommandType.StoredProcedure);
return resultList;
}
}
}
并从 mysql 获取 ID 或对象,您的存储过程应如下所示:
declare id int default 0;
insert into objectTable(fields...)
values (fieldvalue...);
set id=last_insert_id();
select * from objectTable where objectTableid=id;
** 请注意Mysql 存储过程参数名称应与 .Net Core 中的对象属性匹配。
希望这对使用 MySql 存储过程和 .Net Core
的人有所帮助