ack*_*ckh 8 sql dapper sql-insert
使用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; }
}
Run Code Online (Sandbox Code Playgroud)
这里的关键在于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);
}
Run Code Online (Sandbox Code Playgroud)
这很整洁,因为我不必写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);
}
Run Code Online (Sandbox Code Playgroud)
但是,这只是抛出一个InvalidOperationException异常消息"在此上下文中不允许使用可枚举的参数序列(数组,列表等)".
我坚持这个.我怎样才能做到这一点?
我是否必须循环IEnumerable执行Query为循环体内的每个对象执行的输入?这样,如果我想在同一个事务中插入所有对象,那么方法的IDbTransaction参数Query将是无用的,User因此我必须将整个循环包装在事务中而不是将事务传递给Query.
使用Dapper插入多个对象并将完全填充的对象返回给调用者的"正确"方法是什么?
使用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();
...
}
Run Code Online (Sandbox Code Playgroud)
您应该只使用Execute进行多次插入或更新
Execute("your_query",your_list, your_transaction);
Run Code Online (Sandbox Code Playgroud)
因此,如果您需要多次插入并返回插入记录的ID
// **using transaction depend on your needs**
Run Code Online (Sandbox Code Playgroud)
//多次插入并返回完整记录的示例
string query = @"Insert Into _TableName ( _columns)
OUTPUT INSERTED.*
values ( _parameters )"; //parameters should be same as object properties name to let dapper do correct mapping
Run Code Online (Sandbox Code Playgroud)
[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
Run Code Online (Sandbox Code Playgroud)
//对于大列表,您可以使用SqlBulkCopy 在这里查看此链接