使用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
关键字。相反,数据库将填充这些值。
因为对象因此被修改为插入操作的一部分,所以我想返回IEnumerable
类型的另一个User
对象,但这次填充了相应的属性。
最近我意识到我可以让Dapper循环遍历User
中的IEnumerable
对象,如下所示:
public int Insert(IEnumerable<User> users)
{
string sql = string.Format("INSERT INTO [User] (Username) VALUES (@Username)");
return GetOpenConnection().Execute<User>(sql, users);
}
这很整洁,因为我不必自己写foreach
。现在,问题是Execute
只会返回实际插入的行数。
所以我使用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);
}
但是,这只会抛出一个带有消息&#34的InvalidOperationException
异常;在此上下文中不允许使用可枚举的参数序列(数组,列表等)。
我坚持这个。我怎样才能做到这一点?
我是否必须为循环体内的每个对象循环执行IEnumerable
输入Query
?这样,如果我想在同一个事务中插入所有IDbTransaction
个对象,Query
方法的User
参数将毫无用处,因此我必须将整个循环包装在一个事务而不是将事务传递给Query
。
什么是&#34;适当的&#34;使用Dapper插入多个对象的方法,并将完全填充的对象返回给调用者?
答案 0 :(得分:4)
使用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);
所以如果你需要多插入并返回插入记录的ID
// **using transaction depend on your needs**
//多插入和返回完整记录的示例
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。*] 将返回带有id的完整插入行,您可以通过使用属性名称 [OUTPUT INSERTED.Id] 替换星号来返回任何属性仅返回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 查看此链接here
答案 1 :(得分:0)
对于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的人